From 17662abef1fcbffc852ca5d538c9307a5ef15341 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:42:40 +0800 Subject: [PATCH 1/3] Fixed bug where certain null objects in deserialization was not handled --- .../Serialisation/SerialisationUtilities.h++ | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ index dde6705a..2c943452 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ @@ -142,6 +142,31 @@ namespace SHADE bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { System::Object^ valueObj = fieldInfo->GetValue(object); + if (valueObj == nullptr) + { + if constexpr (std::is_same_v) + { + if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) + { + valueObj = 0; + } + } + else + { + if (fieldInfo->FieldType == FieldType::typeid) + { + if constexpr (std::is_same_v) + { + valueObj = ""; + } + else + { + valueObj = FieldType(); + } + } + } + } + if (varAssignYamlInternal(valueObj, node)) { fieldInfo->SetValue(object, valueObj); From 6efbea54e169dac2753255e6ac5ee1959b76b237 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:43:35 +0800 Subject: [PATCH 2/3] Fixed issue where scripts of Entities destroyed during scene unloading are not properly disposed --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 2 +- SHADE_Managed/src/Scripts/ScriptStore.cxx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 0db11c7a..e0b87bea 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -307,7 +307,7 @@ namespace SHADE SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) { auto eventData = reinterpret_cast*>(eventPtr.get()); - csScriptsRemoveAll(eventData->data->eid); + csScriptsRemoveAllImmediately(eventData->data->eid, true); return eventData->handle; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index d57122ee..29ba6e52 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -402,8 +402,8 @@ namespace SHADE System::Collections::Generic::List^ scriptList = scripts[entity]; for each (Script ^ script in scriptList) { - // Call OnDestroy only if indicated and also in play mode - if (callOnDestroy) + // Call OnDestroy only if indicated and also if the game has run + if (callOnDestroy && Application::IsPlaying || Application::IsPaused) { script->OnDestroy(); } @@ -469,7 +469,7 @@ namespace SHADE script->OnDestroy(); } auto entity = script->Owner.GetEntity(); - auto scriptList = scripts[script->Owner.GetEntity()]; + auto scriptList = scripts[script->Owner.GetEntity()]; // Unable to find here scriptList->Remove(script); if (scriptList->Count <= 0) { From 042bff5c1ad1639e552c82775d5f8d0174096ce9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:49:06 +0800 Subject: [PATCH 3/3] Added additional exception handling for serialization and deserialization failures for scripts to prevent data loss --- .../Serialisation/SerialisationUtilities.cxx | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx index 147591a5..cfa94540 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx @@ -45,12 +45,22 @@ namespace SHADE System::Collections::Generic::IEnumerable^ fields = ReflectionUtilities::GetInstanceFields(object); for each (FieldInfo^ field in fields) { - // Ignore private and non-SerialiseField - if (!ReflectionUtilities::FieldIsSerialisable(field)) - continue; + try + { + // Ignore private and non-SerialiseField + if (!ReflectionUtilities::FieldIsSerialisable(field)) + continue; - // Serialise - writeFieldIntoYaml(field, object, scriptNode); + // Serialise + writeFieldIntoYaml(field, object, scriptNode); + } + catch (System::Exception^ e) + { + Debug::LogError + ( + System::String::Format("[SerialisationUtilities] Failed to serialise field ({0}): {1}", field->Name, e->ToString()) + ); + } } scriptListNode.push_back(scriptNode); @@ -74,15 +84,25 @@ namespace SHADE System::Collections::Generic::IEnumerable^ fields = ReflectionUtilities::GetInstanceFields(object); for each (FieldInfo^ field in fields) { - // Ignore private and non-SerialiseField - if (!ReflectionUtilities::FieldIsSerialisable(field)) - continue; - - // Deserialise - const std::string FIELD_NAME = Convert::ToNative(field->Name); - if (yamlNode[FIELD_NAME]) + try { - writeYamlIntoField(field, object, yamlNode[FIELD_NAME]); + // Ignore private and non-SerialiseField + if (!ReflectionUtilities::FieldIsSerialisable(field)) + continue; + + // Deserialise + const std::string FIELD_NAME = Convert::ToNative(field->Name); + if (yamlNode[FIELD_NAME]) + { + writeYamlIntoField(field, object, yamlNode[FIELD_NAME]); + } + } + catch (System::Exception^ e) + { + Debug::LogError + ( + System::String::Format("[SerialisationUtilities] Failed to deserialise field ({0}): {1}", field->Name, e->ToString()) + ); } } }