Fix crash when using Visual Script runtime in async

This commit is contained in:
Wojtek Figat
2023-10-01 10:55:48 +02:00
parent b960600102
commit 0ae413d4fe

View File

@@ -187,6 +187,7 @@ void VisualScriptExecutor::ProcessGroupParameters(Box* box, Node* node, Value& v
break;
}
const auto param = stack.Stack->Script->Graph.GetParameter((Guid)node->Values[0], paramIndex);
ScopeLock lock(stack.Stack->Script->Locker);
const auto instanceParams = stack.Stack->Script->_instances.Find(stack.Stack->Instance->GetID());
if (param && instanceParams)
{
@@ -211,6 +212,7 @@ void VisualScriptExecutor::ProcessGroupParameters(Box* box, Node* node, Value& v
break;
}
const auto param = stack.Stack->Script->Graph.GetParameter((Guid)node->Values[0], paramIndex);
ScopeLock lock(stack.Stack->Script->Locker);
const auto instanceParams = stack.Stack->Script->_instances.Find(stack.Stack->Instance->GetID());
if (param && instanceParams)
{
@@ -1510,6 +1512,7 @@ void VisualScript::unload(bool isReloading)
// Note: preserve the registered scripting type but invalidate the locally cached handle
if (_scriptingTypeHandle)
{
VisualScriptingModule.Locker.Lock();
auto& type = VisualScriptingModule.Types[_scriptingTypeHandle.TypeIndex];
if (type.Script.DefaultInstance)
{
@@ -1520,6 +1523,7 @@ void VisualScript::unload(bool isReloading)
VisualScriptingModule.Scripts[_scriptingTypeHandle.TypeIndex] = nullptr;
_scriptingTypeHandleCached = _scriptingTypeHandle;
_scriptingTypeHandle = ScriptingTypeHandle();
VisualScriptingModule.Locker.Unlock();
}
}
@@ -1531,6 +1535,7 @@ AssetChunksFlag VisualScript::getChunksToPreload() const
void VisualScript::CacheScriptingType()
{
auto& binaryModule = VisualScriptingModule;
ScopeLock lock(binaryModule.Locker);
// Find base type
const StringAnsi baseTypename(Meta.BaseTypename);
@@ -1664,6 +1669,7 @@ ScriptingObject* VisualScriptingBinaryModule::VisualScriptObjectSpawn(const Scri
VisualScript* visualScript = VisualScriptingModule.Scripts[params.Type.TypeIndex];
// Initialize instance data
ScopeLock lock(visualScript->Locker);
auto& instanceParams = visualScript->_instances[object->GetID()].Params;
instanceParams.Resize(visualScript->Graph.Parameters.Count());
for (int32 i = 0; i < instanceParams.Count(); i++)
@@ -1766,6 +1772,7 @@ void VisualScriptingBinaryModule::OnEvent(ScriptingObject* object, Span<Variant>
{
if (const auto visualScript = ScriptingObject::Cast<VisualScript>(asset.Value))
{
visualScript->Locker.Lock();
for (auto& e : visualScript->_instances)
{
auto instance = &e.Value;
@@ -1780,6 +1787,7 @@ void VisualScriptingBinaryModule::OnEvent(ScriptingObject* object, Span<Variant>
called = true;
}
}
visualScript->Locker.Unlock();
if (called)
break;
}
@@ -1824,6 +1832,7 @@ bool VisualScriptingBinaryModule::FindScriptingType(const StringAnsiView& typeNa
void* VisualScriptingBinaryModule::FindMethod(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name, int32 numParams)
{
ScopeLock lock(Locker);
return (void*)Scripts[typeHandle.TypeIndex]->FindMethod(name, numParams);
}
@@ -1855,6 +1864,7 @@ void VisualScriptingBinaryModule::GetMethodSignature(void* method, ScriptingType
void* VisualScriptingBinaryModule::FindField(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name)
{
ScopeLock lock(Locker);
return (void*)Scripts[typeHandle.TypeIndex]->FindField(name);
}
@@ -1875,6 +1885,7 @@ bool VisualScriptingBinaryModule::GetFieldValue(void* field, const Variant& inst
LOG(Error, "Failed to get field '{0}' without object instance", vsFiled->Parameter->Name);
return true;
}
ScopeLock lock(vsFiled->Script->Locker);
const auto instanceParams = vsFiled->Script->_instances.Find(instanceObject->GetID());
if (!instanceParams)
{
@@ -1894,6 +1905,7 @@ bool VisualScriptingBinaryModule::SetFieldValue(void* field, const Variant& inst
LOG(Error, "Failed to set field '{0}' without object instance", vsFiled->Parameter->Name);
return true;
}
ScopeLock lock(vsFiled->Script->Locker);
const auto instanceParams = vsFiled->Script->_instances.Find(instanceObject->GetID());
if (!instanceParams)
{
@@ -1908,9 +1920,12 @@ void VisualScriptingBinaryModule::SerializeObject(JsonWriter& stream, ScriptingO
{
char idName[33];
stream.StartObject();
Locker.Lock();
const auto asset = Scripts[object->GetTypeHandle().TypeIndex].Get();
Locker.Unlock();
if (asset)
{
ScopeLock lock(asset->Locker);
const auto instanceParams = asset->_instances.Find(object->GetID());
if (instanceParams)
{
@@ -1970,9 +1985,12 @@ void VisualScriptingBinaryModule::SerializeObject(JsonWriter& stream, ScriptingO
void VisualScriptingBinaryModule::DeserializeObject(ISerializable::DeserializeStream& stream, ScriptingObject* object, ISerializeModifier* modifier)
{
ASSERT(stream.IsObject());
Locker.Lock();
const auto asset = Scripts[object->GetTypeHandle().TypeIndex].Get();
Locker.Unlock();
if (asset)
{
ScopeLock lock(asset->Locker);
const auto instanceParams = asset->_instances.Find(object->GetID());
if (instanceParams)
{
@@ -1997,9 +2015,12 @@ void VisualScriptingBinaryModule::DeserializeObject(ISerializable::DeserializeSt
void VisualScriptingBinaryModule::OnObjectIdChanged(ScriptingObject* object, const Guid& oldId)
{
Locker.Lock();
const auto asset = Scripts[object->GetTypeHandle().TypeIndex].Get();
Locker.Unlock();
if (asset)
{
ScopeLock lock(asset->Locker);
auto& instanceParams = asset->_instances[object->GetID()];
auto oldParams = asset->_instances.Find(oldId);
if (oldParams)
@@ -2012,10 +2033,13 @@ void VisualScriptingBinaryModule::OnObjectIdChanged(ScriptingObject* object, con
void VisualScriptingBinaryModule::OnObjectDeleted(ScriptingObject* object)
{
Locker.Lock();
const auto asset = Scripts[object->GetTypeHandle().TypeIndex].Get();
Locker.Unlock();
if (asset)
{
// Cleanup object data
ScopeLock lock(asset->Locker);
asset->_instances.Remove(object->GetID());
}
}
@@ -2031,10 +2055,12 @@ void VisualScriptingBinaryModule::Destroy(bool isReloading)
ScriptingTypeHandle VisualScript::GetScriptingType()
{
if (!_scriptingTypeHandle && !WaitForLoaded())
{
if (WaitForLoaded())
return ScriptingTypeHandle();
Locker.Lock();
if (!_scriptingTypeHandle)
CacheScriptingType();
}
Locker.Unlock();
return _scriptingTypeHandle;
}
@@ -2046,7 +2072,14 @@ ScriptingObject* VisualScript::CreateInstance()
VisualScript::Instance* VisualScript::GetScriptInstance(ScriptingObject* instance) const
{
return instance ? _instances.TryGet(instance->GetID()) : nullptr;
Instance* result = nullptr;
if (instance)
{
Locker.Lock();
result = _instances.TryGet(instance->GetID());
Locker.Unlock();
}
return result;
}
const Variant& VisualScript::GetScriptInstanceParameterValue(const StringView& name, ScriptingObject* instance) const
@@ -2074,6 +2107,7 @@ void VisualScript::SetScriptInstanceParameterValue(const StringView& name, Scrip
{
if (Graph.Parameters[paramIndex].Name == name)
{
ScopeLock lock(Locker);
const auto instanceParams = _instances.Find(instance->GetID());
if (instanceParams)
{
@@ -2094,6 +2128,7 @@ void VisualScript::SetScriptInstanceParameterValue(const StringView& name, Scrip
{
if (Graph.Parameters[paramIndex].Name == name)
{
ScopeLock lock(Locker);
const auto instanceParams = _instances.Find(instance->GetID());
if (instanceParams)
{