diff --git a/sp/src/vscript/vscript_squirrel.cpp b/sp/src/vscript/vscript_squirrel.cpp index f3d0516e..563f5b4c 100644 --- a/sp/src/vscript/vscript_squirrel.cpp +++ b/sp/src/vscript/vscript_squirrel.cpp @@ -1218,6 +1218,14 @@ HSCRIPT SquirrelVM::CreateScope(const char* pszScope, HSCRIPT hParent) sq_pushroottable(vm_); } + sq_pushstring(vm_, pszScope, -1); + sq_push(vm_, -3); + sq_rawset(vm_, -3); + + sq_pushstring(vm_, "__vname", -1); + sq_pushstring(vm_, pszScope, -1); + sq_rawset(vm_, -4); + if (SQ_FAILED(sq_setdelegate(vm_, -2))) { sq_pop(vm_, 2); @@ -1238,6 +1246,15 @@ void SquirrelVM::ReleaseScope(HSCRIPT hScript) SquirrelSafeCheck safeCheck(vm_); if (!hScript) return; HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_pushobject(vm_, *obj); + + sq_getdelegate(vm_, -1); + + sq_pushstring(vm_, "__vname", -1); + sq_rawdeleteslot(vm_, -2, SQFalse); + + sq_pop(vm_, 2); + sq_release(vm_, obj); delete obj; } @@ -1930,6 +1947,17 @@ void SquirrelVM::WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQI sq_poptop(vm_); } } + + if (_closure(obj)->_env) + { + sq_pushobject(vm_, _closure(obj)->_env->_obj); + } + else + { + sq_pushnull(vm_); + } + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); break; } @@ -2077,7 +2105,11 @@ void SquirrelVM::WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQI if (pClassInstanceData) { - if (pClassInstanceData->instanceId) + if (pClassInstanceData->desc->m_pszDescription[0] == SCRIPT_SINGLETON[0]) + { + // Do nothing, singleton should be created from just the class + } + else if (!pClassInstanceData->instanceId.IsEmpty()) { pBuffer->PutString(pClassInstanceData->instanceId); } @@ -2150,6 +2182,12 @@ void SquirrelVM::WriteState(CUtlBuffer* pBuffer) sq_pushroottable(vm_); + // Not really a check cache, but adds the root + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, -1, &obj); + writeState.CheckCache(pBuffer, _table(obj)); + int count = sq_getsize(vm_, 1); sq_pushnull(vm_); pBuffer->PutInt(count); @@ -2204,6 +2242,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) int size = pBuffer->GetInt(); char* buffer = new char[size + 1]; pBuffer->Get(buffer, size); + buffer[size] = 0; sq_pushstring(vm_, buffer, size); delete[] buffer; break; @@ -2234,6 +2273,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) ReadObject(pBuffer, readState); sq_rawset(vm_, -3); } + break; } case OT_ARRAY: @@ -2301,6 +2341,16 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_pushobject(vm_, *obj); } + ReadObject(pBuffer, readState); + HSQOBJECT env; + sq_resetobject(&env); + sq_getstackobj(vm_, -1, &env); + if (!sq_isnull(env)) + { + _closure(*obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env)); + } + sq_poptop(vm_); + break; } case OT_NATIVECLOSURE: @@ -2317,6 +2367,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) sq_pushnull(vm_); } sq_remove(vm_, -2); + break; } case OT_CLASS: @@ -2392,6 +2443,49 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) ReadObject(pBuffer, readState); + SQUserPointer typetag; + sq_gettypetag(vm_, -1, &typetag); + + if (typetag && typetag != TYPETAG_VECTOR && + ((ScriptClassDesc_t*)typetag)->m_pszDescription[0] == SCRIPT_SINGLETON[0]) + { + HSQOBJECT klass; + sq_resetobject(&klass); + sq_getstackobj(vm_, -1, &klass); + sq_poptop(vm_); + + Assert(sq_isclass(klass)); + + // singleton, lets find an equivlent in the root + bool foundSingleton = false; + sq_pushroottable(vm_); + sq_pushnull(vm_); + HSQOBJECT singleton; + sq_resetobject(&singleton); + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + sq_getstackobj(vm_, -1, &singleton); + if (sq_isinstance(singleton) && _instance(singleton)->_class == _class(klass)) + { + foundSingleton = true; + *obj = singleton; + sq_pop(vm_, 2); + break; + } + sq_pop(vm_, 2); + } + sq_pop(vm_, 2); + + if (!foundSingleton) + { + Warning("SquirrelVM::ReadObject: Failed to find singleton for %s\n", + ((ScriptClassDesc_t*)typetag)->m_pszScriptName); + } + + sq_pushobject(vm_, *obj); + break; + } + sq_createinstance(vm_, -1); sq_getstackobj(vm_, -1, obj); @@ -2410,8 +2504,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } } - SQUserPointer typetag; - sq_gettypetag(vm_, -1, &typetag); + if (typetag == TYPETAG_VECTOR) { @@ -2453,6 +2546,10 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } sq_setreleasehook(vm_, -1, &destructor_stub); } + else + { + sq_setinstanceup(vm_, -1, nullptr); + } } break; @@ -2481,6 +2578,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) } vm_->Push(ret); + sq_getstackobj(vm_, -1, obj); } case OT_OUTER: //internal usage only { @@ -2500,6 +2598,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) outer->_valptr = &(outer->_value); sq_poptop(vm_); vm_->Push(outer); + sq_getstackobj(vm_, -1, obj); break; } @@ -2521,6 +2620,10 @@ void SquirrelVM::ReadState(CUtlBuffer* pBuffer) sq_pushroottable(vm_); + HSQOBJECT* obj = nullptr; + readState.CheckCache(pBuffer, &obj); + sq_getstackobj(vm_, -1, obj); + int count = pBuffer->GetInt(); for (int i = 0; i < count; ++i)