Fixed edge cases for serialization and deserialization of scripts #218

Merged
Pycorax merged 3 commits from SP3-6-c-scripting into main 2022-11-17 17:17:13 +08:00
4 changed files with 62 additions and 17 deletions

View File

@ -307,7 +307,7 @@ namespace SHADE
SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr)
{ {
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get()); auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
csScriptsRemoveAll(eventData->data->eid); csScriptsRemoveAllImmediately(eventData->data->eid, true);
return eventData->handle; return eventData->handle;
} }

View File

@ -402,8 +402,8 @@ namespace SHADE
System::Collections::Generic::List<Script^>^ scriptList = scripts[entity]; System::Collections::Generic::List<Script^>^ scriptList = scripts[entity];
for each (Script ^ script in scriptList) for each (Script ^ script in scriptList)
{ {
// Call OnDestroy only if indicated and also in play mode // Call OnDestroy only if indicated and also if the game has run
if (callOnDestroy) if (callOnDestroy && Application::IsPlaying || Application::IsPaused)
{ {
script->OnDestroy(); script->OnDestroy();
} }
@ -469,7 +469,7 @@ namespace SHADE
script->OnDestroy(); script->OnDestroy();
} }
auto entity = script->Owner.GetEntity(); auto entity = script->Owner.GetEntity();
auto scriptList = scripts[script->Owner.GetEntity()]; auto scriptList = scripts[script->Owner.GetEntity()]; // Unable to find here
scriptList->Remove(script); scriptList->Remove(script);
if (scriptList->Count <= 0) if (scriptList->Count <= 0)
{ {

View File

@ -45,12 +45,22 @@ namespace SHADE
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = ReflectionUtilities::GetInstanceFields(object); System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = ReflectionUtilities::GetInstanceFields(object);
for each (FieldInfo^ field in fields) for each (FieldInfo^ field in fields)
{ {
// Ignore private and non-SerialiseField try
if (!ReflectionUtilities::FieldIsSerialisable(field)) {
continue; // Ignore private and non-SerialiseField
if (!ReflectionUtilities::FieldIsSerialisable(field))
continue;
// Serialise // Serialise
writeFieldIntoYaml(field, object, scriptNode); 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); scriptListNode.push_back(scriptNode);
@ -74,15 +84,25 @@ namespace SHADE
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = ReflectionUtilities::GetInstanceFields(object); System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = ReflectionUtilities::GetInstanceFields(object);
for each (FieldInfo^ field in fields) for each (FieldInfo^ field in fields)
{ {
// Ignore private and non-SerialiseField try
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]); // 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())
);
} }
} }
} }

View File

@ -142,6 +142,31 @@ namespace SHADE
bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
{ {
System::Object^ valueObj = fieldInfo->GetValue(object); System::Object^ valueObj = fieldInfo->GetValue(object);
if (valueObj == nullptr)
{
if constexpr (std::is_same_v<FieldType, System::Enum>)
{
if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
{
valueObj = 0;
}
}
else
{
if (fieldInfo->FieldType == FieldType::typeid)
{
if constexpr (std::is_same_v<FieldType, System::String>)
{
valueObj = "";
}
else
{
valueObj = FieldType();
}
}
}
}
if (varAssignYamlInternal<FieldType>(valueObj, node)) if (varAssignYamlInternal<FieldType>(valueObj, node))
{ {
fieldInfo->SetValue(object, valueObj); fieldInfo->SetValue(object, valueObj);