mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 23:35:30 +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_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)))
|
if (SQ_FAILED(sq_setdelegate(vm_, -2)))
|
||||||
{
|
{
|
||||||
sq_pop(vm_, 2);
|
sq_pop(vm_, 2);
|
||||||
@ -1238,6 +1246,15 @@ void SquirrelVM::ReleaseScope(HSCRIPT hScript)
|
|||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
if (!hScript) return;
|
if (!hScript) return;
|
||||||
HSQOBJECT* obj = (HSQOBJECT*)hScript;
|
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);
|
sq_release(vm_, obj);
|
||||||
delete 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;
|
break;
|
||||||
}
|
}
|
||||||
case OT_NATIVECLOSURE:
|
case OT_NATIVECLOSURE:
|
||||||
@ -2077,7 +2105,11 @@ void SquirrelVM::WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQI
|
|||||||
|
|
||||||
if (pClassInstanceData)
|
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);
|
pBuffer->PutString(pClassInstanceData->instanceId);
|
||||||
}
|
}
|
||||||
@ -2150,6 +2182,12 @@ void SquirrelVM::WriteState(CUtlBuffer* pBuffer)
|
|||||||
|
|
||||||
sq_pushroottable(vm_);
|
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);
|
int count = sq_getsize(vm_, 1);
|
||||||
sq_pushnull(vm_);
|
sq_pushnull(vm_);
|
||||||
pBuffer->PutInt(count);
|
pBuffer->PutInt(count);
|
||||||
@ -2204,6 +2242,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
int size = pBuffer->GetInt();
|
int size = pBuffer->GetInt();
|
||||||
char* buffer = new char[size + 1];
|
char* buffer = new char[size + 1];
|
||||||
pBuffer->Get(buffer, size);
|
pBuffer->Get(buffer, size);
|
||||||
|
buffer[size] = 0;
|
||||||
sq_pushstring(vm_, buffer, size);
|
sq_pushstring(vm_, buffer, size);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
break;
|
break;
|
||||||
@ -2234,6 +2273,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
ReadObject(pBuffer, readState);
|
ReadObject(pBuffer, readState);
|
||||||
sq_rawset(vm_, -3);
|
sq_rawset(vm_, -3);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OT_ARRAY:
|
case OT_ARRAY:
|
||||||
@ -2301,6 +2341,16 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
sq_pushobject(vm_, *obj);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case OT_NATIVECLOSURE:
|
case OT_NATIVECLOSURE:
|
||||||
@ -2317,6 +2367,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
sq_pushnull(vm_);
|
sq_pushnull(vm_);
|
||||||
}
|
}
|
||||||
sq_remove(vm_, -2);
|
sq_remove(vm_, -2);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OT_CLASS:
|
case OT_CLASS:
|
||||||
@ -2392,6 +2443,49 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
|
|
||||||
ReadObject(pBuffer, 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_createinstance(vm_, -1);
|
||||||
sq_getstackobj(vm_, -1, obj);
|
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)
|
if (typetag == TYPETAG_VECTOR)
|
||||||
{
|
{
|
||||||
@ -2453,6 +2546,10 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
}
|
}
|
||||||
sq_setreleasehook(vm_, -1, &destructor_stub);
|
sq_setreleasehook(vm_, -1, &destructor_stub);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_setinstanceup(vm_, -1, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -2481,6 +2578,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm_->Push(ret);
|
vm_->Push(ret);
|
||||||
|
sq_getstackobj(vm_, -1, obj);
|
||||||
}
|
}
|
||||||
case OT_OUTER: //internal usage only
|
case OT_OUTER: //internal usage only
|
||||||
{
|
{
|
||||||
@ -2500,6 +2598,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
outer->_valptr = &(outer->_value);
|
outer->_valptr = &(outer->_value);
|
||||||
sq_poptop(vm_);
|
sq_poptop(vm_);
|
||||||
vm_->Push(outer);
|
vm_->Push(outer);
|
||||||
|
sq_getstackobj(vm_, -1, obj);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2521,6 +2620,10 @@ void SquirrelVM::ReadState(CUtlBuffer* pBuffer)
|
|||||||
|
|
||||||
sq_pushroottable(vm_);
|
sq_pushroottable(vm_);
|
||||||
|
|
||||||
|
HSQOBJECT* obj = nullptr;
|
||||||
|
readState.CheckCache(pBuffer, &obj);
|
||||||
|
sq_getstackobj(vm_, -1, obj);
|
||||||
|
|
||||||
int count = pBuffer->GetInt();
|
int count = pBuffer->GetInt();
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
|
Loading…
Reference in New Issue
Block a user