diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp index 63b52493f08..067df278111 100644 --- a/engines/director/cast.cpp +++ b/engines/director/cast.cpp @@ -1228,6 +1228,10 @@ void Cast::loadLingoContext(Common::SeekableReadStreamEndian &stream) { error("Cast::loadLingoContext: Script already defined for type %s, id %d", scriptType2str(script->_scriptType), script->_id); } _lingoArchive->scriptContexts[script->_scriptType][script->_id] = script; + } else { + // Keep track of scripts that are not in scriptContexts + // Those scripts need to be cleaned up on ~LingoArchive + script->setOnlyInLctxContexts(); } } } else { diff --git a/engines/director/lingo/lingo-object.h b/engines/director/lingo/lingo-object.h index 4d9dc8981a1..a8cc87c15f0 100644 --- a/engines/director/lingo/lingo-object.h +++ b/engines/director/lingo/lingo-object.h @@ -200,6 +200,9 @@ public: DatumHash _properties; Common::HashMap _objArray; +private: + bool _onlyInLctxContexts = false; + public: ScriptContext(Common::String name, ScriptType type = kNoneScript, int id = 0); ScriptContext(const ScriptContext &sc); @@ -208,6 +211,9 @@ public: bool isFactory() const { return _objType == kFactoryObj; }; void setFactory(bool flag) { _objType = flag ? kFactoryObj : kScriptObj; } + void setOnlyInLctxContexts() { _onlyInLctxContexts = true; } + bool getOnlyInLctxContexts() { return _onlyInLctxContexts; } + Common::String asString() override; Symbol getMethod(const Common::String &methodName) override; bool hasProp(const Common::String &propName) override; diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index 0059326518b..413d8bd85aa 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -227,6 +227,15 @@ void Lingo::reloadBuiltIns() { } LingoArchive::~LingoArchive() { + + // First cleanup the ScriptContexts that are only in LctxContexts. + // LctxContexts has a huge overlap with scriptContexts. + for (ScriptContextHash::iterator it = lctxContexts.begin(); it != lctxContexts.end(); ++it){ + ScriptContext *script = it->_value; + if (script->getOnlyInLctxContexts()) + delete script; + } + for (int i = 0; i <= kMaxScriptType; i++) { for (ScriptContextHash::iterator it = scriptContexts[i].begin(); it != scriptContexts[i].end(); ++it) { *it->_value->_refCount -= 1;