diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 3bdbe90e..f371686c 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -41,7 +41,12 @@ namespace SHADE bool ReflectionUtilities::FieldIsList(System::Reflection::FieldInfo^ fieldInfo) { - return fieldInfo->FieldType->IsGenericType - && fieldInfo->FieldType->GetGenericTypeDefinition() == System::Collections::Generic::List::typeid->GetGenericTypeDefinition(); + return IsList(fieldInfo->FieldType); + } + + bool ReflectionUtilities::IsList(System::Type^ type) + { + return type->IsGenericType + && type->GetGenericTypeDefinition() == System::Collections::Generic::List::typeid->GetGenericTypeDefinition(); } } diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx index ffdc208f..ae66cc34 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx @@ -45,5 +45,11 @@ namespace SHADE /// The field to check. /// True if fieldInfo is describing a generic List. static bool FieldIsList(System::Reflection::FieldInfo^ fieldInfo); + /// + /// Checks if the specified type is a generic List type. + /// + /// The type to check. + /// True if type is a generic List. + static bool IsList(System::Type^ type); }; } \ No newline at end of file diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx index e8a4e0e3..20880947 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx @@ -173,79 +173,88 @@ namespace SHADE varInsertYamlInternal(object, fieldNode); return INSERTED; } - - void SerialisationUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) + + /*---------------------------------------------------------------------------------*/ + /* Deserialization Helper Functions */ + /*---------------------------------------------------------------------------------*/ + bool SerialisationUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { - if (fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node)) + const bool ASSIGNED = + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node); + if (!ASSIGNED) { - return; - } - else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) - { - fieldInfo->SetValue(object, node.as()); - } - else if (fieldInfo->FieldType == System::String::typeid) - { - fieldInfo->SetValue(object, Convert::ToCLI(node.as())); - } - else if (fieldInfo->FieldType == Vector2::typeid) - { - if (node.IsSequence() && node.size() == 2) + if (ReflectionUtilities::FieldIsList(fieldInfo)) { - Vector2 vec; - vec.x = node[0].as(); - vec.y = node[1].as(); - fieldInfo->SetValue(object, vec); - } - else - { - Debug::LogWarning - ( - System::String::Format("[SerialisationUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.", - fieldInfo->Name, object->GetType()->FullName) - ); + System::Type^ elemType = fieldInfo->FieldType->GenericTypeArguments[0]; + System::Collections::IList^ iList = safe_cast(fieldInfo->GetValue(object)); + if (node.IsSequence()) + { + // Get list size + const int LIST_SIZE = static_cast(node.size()); + if (LIST_SIZE > 0) + { + // Get list type + array^ typeList = gcnew array{ elemType }; + System::Type^ listType = System::Collections::Generic::List::typeid->GetGenericTypeDefinition()->MakeGenericType(typeList); + // Create a list of the specified type + array^ params = gcnew array{ node.size() }; + object = System::Activator::CreateInstance(listType, params); + System::Collections::IList^ list = safe_cast(object); + + // Populate the list + for (int i = 0; i < LIST_SIZE; ++i) + { + // Create the object + System::Object^ obj = System::Activator::CreateInstance(elemType); + + // Set it's value + if (varAssignYaml(obj, node[i])) + { + list->Add(obj); + } + } + } + } + + return true; } } - else if (fieldInfo->FieldType == Vector3::typeid) - { - if (node.IsSequence() && node.size() == 3) - { - Vector3 vec; - vec.x = node[0].as(); - vec.y = node[1].as(); - vec.z = node[2].as(); - fieldInfo->SetValue(object, vec); - } - else - { - Debug::LogWarning - ( - System::String::Format("[SerialisationUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.", - fieldInfo->Name, object->GetType()->FullName) - ); - } - } - else if (fieldInfo->FieldType == GameObject::typeid) - { - const uint32_t EID = node.as(); - fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID)); - } - else // Not any of the supported types - { - Debug::LogWarning(Convert::ToNative(System::String::Format - ( - "[SerialisationUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.", - fieldInfo->Name, fieldInfo->FieldType) - )); - } + + return ASSIGNED; + } + + bool SerialisationUtilities::varAssignYaml(System::Object^% object, YAML::Node& node) + { + const bool DESERIALISED = + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node) || + varAssignYamlInternal (object, node); + return DESERIALISED; } } diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ index 93a14401..c1728fe6 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ @@ -36,7 +36,6 @@ namespace SHADE { if constexpr (std::is_same_v) { - Debug::Log("Enum Specialization"); if (object->GetType()->IsSubclassOf(System::Enum::typeid)) { fieldNode = std::to_string(safe_cast(object)); @@ -45,7 +44,6 @@ namespace SHADE } else if constexpr (std::is_same_v) { - Debug::Log("String Specialization"); if (object->GetType() == System::String::typeid) { System::String^ str = safe_cast(object); @@ -55,7 +53,6 @@ namespace SHADE } else if constexpr (std::is_same_v) { - Debug::Log("Vec2 Specialization"); if (object->GetType() == Vector2::typeid) { Vector2 vec = safe_cast(object); @@ -67,7 +64,6 @@ namespace SHADE } else if constexpr (std::is_same_v) { - Debug::Log("Vec3 Specialization"); if (object->GetType() == Vector3::typeid) { Vector3 vec = safe_cast(object); @@ -80,7 +76,6 @@ namespace SHADE } else if constexpr (std::is_same_v) { - Debug::Log("GameObject Specialization"); if (object->GetType() == GameObject::typeid) { GameObject gameObj = safe_cast(object); @@ -90,7 +85,6 @@ namespace SHADE } else { - Debug::Log("No Specialization"); if (object->GetType() == FieldType::typeid) { FieldType value = safe_cast(object); @@ -108,18 +102,87 @@ namespace SHADE template bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { - return fieldAssignYaml>(fieldInfo, object, node); - } - - template - bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) - { - if (fieldInfo->FieldType == FieldType::typeid) + System::Object^ valueObj = fieldInfo->GetValue(object); + if (varAssignYamlInternal(valueObj, node)) { - fieldInfo->SetValue(object, node.as()); + fieldInfo->SetValue(object, valueObj); return true; } return false; } + + template + bool SerialisationUtilities::varAssignYamlInternal(System::Object^% object, YAML::Node& node) + { + if constexpr (std::is_same_v) + { + if (object->GetType()->IsSubclassOf(System::Enum::typeid)) + { + object = node.as(); + return true; + } + } + else if constexpr (std::is_same_v) + { + if (ReflectionUtilities::FieldIsList(fieldInfo)) + { + System::Collections::IList^ iList = safe_cast(object); + object = gcnew + if (node.IsSequence() ) + + } + } + else + { + if (object->GetType() == FieldType::typeid) + { + if constexpr (std::is_same_v) + { + object = Convert::ToCLI(node.as()); + } + else if constexpr (std::is_same_v) + { + if (node.IsSequence() && node.size() == 2) + { + Vector2 vec; + vec.x = node[0].as(); + vec.y = node[1].as(); + object = vec; + } + else + { + return false; + } + } + else if constexpr (std::is_same_v) + { + if (node.IsSequence() && node.size() == 3) + { + Vector3 vec; + vec.x = node[0].as(); + vec.y = node[1].as(); + vec.z = node[2].as(); + object = vec; + } + else + { + return false; + } + } + else if constexpr (std::is_same_v) + { + const uint32_t EID = node.as(); + object = (EID == MAX_EID ? GameObject() : GameObject(EID)); + } + else + { + object = node.as(); + } + return true; + } + } + + return false; + } } diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.hxx b/SHADE_Managed/src/Serialisation/SerialisationUtilities.hxx index 93d88248..5b6fc69e 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.hxx +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.hxx @@ -63,11 +63,12 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Deserialization Helper Functions */ /*-----------------------------------------------------------------------------*/ - static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); + static bool writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); template static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); - template - static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); + static bool varAssignYaml(System::Object^% object, YAML::Node& node); + template> + static bool varAssignYamlInternal(System::Object^% object, YAML::Node& node); }; }