diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index b4025d234..105d4ad2d 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -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 { if (const auto visualScript = ScriptingObject::Cast(asset.Value)) { + visualScript->Locker.Lock(); for (auto& e : visualScript->_instances) { auto instance = &e.Value; @@ -1780,6 +1787,7 @@ void VisualScriptingBinaryModule::OnEvent(ScriptingObject* object, Span 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) {