Fix crash when using Visual Script runtime in async
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user