DIRECTOR: LINGO: Add functionHandlers lookup, stop overriding _builtins

This commit is contained in:
Scott Percival 2020-05-28 00:25:09 +08:00
parent 38d27dd9aa
commit 23ad830af3
4 changed files with 32 additions and 25 deletions

View File

@ -283,9 +283,9 @@ Symbol *Lingo::define(Common::String &name, int nargs, ScriptData *code) {
sym->type = HANDLER;
if (!_eventHandlerTypeIds.contains(name)) {
_builtins[name] = sym;
_archives[_archiveIndex].functionHandlers[name] = sym;
} else {
_handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
_archives[_archiveIndex].eventHandlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
}
} else {
// we don't want to be here. The getHandler call should have used the EntityId and the result
@ -660,7 +660,7 @@ void Lingo::codeFactory(Common::String &name) {
sym->parens = true;
sym->u.bltin = LB::b_factory;
_handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
_archives[_archiveIndex].eventHandlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
}
}

View File

@ -94,21 +94,6 @@ ScriptType Lingo::event2script(LEvent ev) {
return kNoneScript;
}
Symbol *Lingo::getHandler(Common::String &name) {
if (!_eventHandlerTypeIds.contains(name)) {
if (_builtins.contains(name))
return _builtins[name];
return NULL;
}
uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId);
if (!_handlers.contains(entityIndex))
return NULL;
return _handlers[entityIndex];
}
void Lingo::primaryEventHandler(LEvent event) {
/* When an event occurs the message [...] is first sent to a
* primary event handler: [... if exists it is executed] and the
@ -330,7 +315,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId, int channelI
if (!_eventHandlerTypes.contains(event))
error("processEvent: Unknown event %d for entity %d", event, entityId);
if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
if (_archives[_archiveIndex].eventHandlers.contains(ENTITY_INDEX(event, entityId))) {
debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId);
executeHandler(_eventHandlerTypes[event]); // D4+ Events
} else if (_vm->getVersion() < 4 && event == kEventNone && getScriptContext(st, entityId)) {

View File

@ -190,9 +190,6 @@ Lingo::~Lingo() {
for (SymbolHash::iterator it = _globalvars.begin(); it != _globalvars.end(); ++it)
delete it->_value;
for (Common::HashMap<uint32, Symbol *>::iterator it = _handlers.begin(); it != _handlers.end(); ++it)
delete it->_value;
}
ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) {
@ -214,6 +211,30 @@ Common::String Lingo::getName(uint16 id) {
return result;
}
Symbol *Lingo::getHandler(Common::String &name) {
if (!_eventHandlerTypeIds.contains(name)) {
// local scripts
if (_archives[0].functionHandlers.contains(name))
return _archives[0].functionHandlers[name];
// shared scripts
if (_archives[1].functionHandlers.contains(name))
return _archives[1].functionHandlers[name];
if (_builtins.contains(name))
return _builtins[name];
return NULL;
}
uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId);
// event handlers should only be defined locally, the score in a shared file is ignored
if (_archives[0].eventHandlers.contains(entityIndex))
return _archives[0].eventHandlers[entityIndex];
return NULL;
}
const char *Lingo::findNextDefinition(const char *s) {
const char *res = s;
@ -413,7 +434,7 @@ void Lingo::restartLingo() {
// custom menus
//
// NOTE:
// tuneousScript is not reset
// timeoutScript is not reset
}
int Lingo::getAlignedType(Datum &d1, Datum &d2) {

View File

@ -255,9 +255,10 @@ struct LingoEvent {
struct LingoArchive {
ScriptContextHash scriptContexts[kMaxScriptType + 1];
Common::Array<Common::String> names;
Common::HashMap<uint32, Symbol *> eventHandlers;
SymbolHash functionHandlers;
};
class Lingo {
public:
@ -419,6 +420,7 @@ public:
ScriptContext *_currentScriptContext;
uint16 _currentScriptFunction;
ScriptData *_currentScript;
bool _returning;
bool _nextRepeat;
LexerDefineState _indef;
@ -436,7 +438,6 @@ public:
Common::Array<int> _labelstack;
SymbolHash _builtins;
Common::HashMap<uint32, Symbol *> _handlers;
int _linenumber;
int _colnumber;