mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 07:15:31 +03:00
Various vscript fixes
* Fixes scopes not being restored from a save * Fixes closure environment not being restored from a save * Fixes singletons not being properly restored from a save * Fixes root table being incorrectly duplicated in a save * Fixes various cases where duplicate objects could be created from a save
This commit is contained in:
parent
33e7a45657
commit
1210dee374
@ -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;
|
||||
}
|
||||
@ -1931,6 +1948,17 @@ void SquirrelVM::WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQI
|
||||
}
|
||||
}
|
||||
|
||||
if (_closure(obj)->_env)
|
||||
{
|
||||
sq_pushobject(vm_, _closure(obj)->_env->_obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_pushnull(vm_);
|
||||
}
|
||||
WriteObject(pBuffer, writeState, -1);
|
||||
sq_poptop(vm_);
|
||||
|
||||
break;
|
||||
}
|
||||
case OT_NATIVECLOSURE:
|
||||
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user