Added YAML serialization of scripts

This commit is contained in:
Kah Wei 2022-09-16 15:37:22 +08:00
parent c89fe48182
commit 4546b84c06
3 changed files with 249 additions and 374 deletions

View File

@ -16,41 +16,17 @@ of DigiPen Institute of Technology is prohibited.
#include "SHpch.h" #include "SHpch.h"
// Primary Header // Primary Header
#include "Serialisation/ReflectionUtilities.hxx" #include "Serialisation/ReflectionUtilities.hxx"
// External Dependencies
// Project Includes // Project Includes
#include "SerializeFieldAttribute.hxx" #include "SerializeFieldAttribute.hxx"
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Math/Vector2.hxx"
#include "Math/Vector3.hxx"
#include "Utility/Debug.hxx"
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/* Macro Functions */ /* Macro Functions */
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Macro expansion that is used in FieldToRapidJsonValue() to check the type of a field
/// named "fieldInfo" against the specified type and if it matches, store said field
/// of an object named "object" it into rapidjson::Value called "jsonValue" as that
/// specified type.
/// </summary>
/// <param name="T">The type to check.</param>
#define PRIMITIVE_FIELD_CAST(T) \
(fieldInfo->FieldType == T::typeid) \
{ \
jsonValue = safe_cast<T>(fieldInfo->GetValue(object)); \
} \
/// <summary>
/// Macro expansion that is used in RapidJsonValueToField() to check the type of a field
/// named "fieldInfo" against the specified type and if it matches, retrieves the value
/// using the function FUNC provided from a rapidjson::Value called "jsonValue" and sets
/// the value of the field to the retrieved value.
/// </summary>
/// <param name="T">The type to check.</param>
/// <param name="FUNC">Member function of jsonValue to use to retrieve the data.</param>
#define PRIMITIVE_FIELD_ASSIGN(T, FUNC) \
(fieldInfo->FieldType == T::typeid) \
{ \
fieldInfo->SetValue(object, jsonValue.FUNC()); \
} \
/// <summary>
/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified /// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified
/// member of a Vector type that is stored into a Vector named "vec". /// member of a Vector type that is stored into a Vector named "vec".
/// </summary> /// </summary>
@ -61,45 +37,7 @@ if (iter != jsonValue.MemberEnd()) \
{ \ { \
vec.MEMBER = iter->value.GetDouble(); \ vec.MEMBER = iter->value.GetDouble(); \
} \ } \
/// <summary>
/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified
/// member of a Color type that is stored into a Color named "col".
/// </summary>
/// <param name="MEMBER">The name of the member to retrieve.</param>
#define PRIMITIVE_COLOR_FIELD_ASSIGN(MEMBER) \
iter = jsonValue.FindMember(#MEMBER); \
if (iter != jsonValue.MemberEnd()) \
{ \
col.MEMBER = iter->value.GetFloat(); \
} \
/// <summary>
/// Macro expansion that is used to write the name of a field named fieldInfo into a
/// rapidjson writer called writer.
/// </summary>
#define PRIMITIVE_WRITE_FIELD_NAME writer.String(Convert::ToNative(fieldInfo->Name).c_str());
/// <summary>
/// Macro expansion that is used in serialiseFieldJson() to check the type of a field
/// named "fieldInfo" against the specified type and if it matches, writes the value
/// using the function FUNC in to a rapidjson writer object named "writer".
/// </summary>
/// <param name="T">The type to check.</param>
/// <param name="FUNC">
/// Member function of the rapidjson writer object to use to write the data.
/// </param>
#define PRIMITIVE_FIELD_SERIALISE_JSON(T, FUNC) \
(fieldInfo->FieldType == T::typeid) \
{ \
PRIMITIVE_WRITE_FIELD_NAME \
writer.FUNC(safe_cast<T>(fieldInfo->GetValue(object))); \
} \
/// <summary>
/// Macro expansion that is used in serialiseFieldJson() to write the specified
/// member of a Vector named "vec" using the rapidjson writer named "writer".
/// </summary>
/// <param name="MEMBER">The name of the member to write.</param>
#define PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(MEMBER) \
writer.String(#MEMBER); \
writer.Double(vec.MEMBER); \
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/* Function Definitions */ /* Function Definitions */
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
@ -123,307 +61,182 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Serialisation Functions */ /* Serialisation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
//void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml)
//{ {
// // Create YAML object using namespace System::Reflection;
// yaml << YAML::Key << Convert::ToNative(object->GetType().FullName);
// yaml << YAML::BeginMap;
// // Get all fields // Create YAML object
// IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object); yaml << YAML::Key << Convert::ToNative(object->GetType()->FullName);
// for each (FieldInfo^ field in fields) yaml << YAML::BeginMap;
// {
// // Ignore private and non-SerialiseField
// if (!FieldIsSerialisable(field))
// continue;
// // Serialise // Get all fields
// rapidjson::Value jsonValue = FieldToRapidJsonValue(field, object, allocator); System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
// rapidjson::Value key(Convert::ToNative(field->Name).c_str(), allocator); for each (FieldInfo^ field in fields)
// scriptRoot.AddMember(key.Move(), jsonValue, allocator); {
// } // Ignore private and non-SerialiseField
if (!FieldIsSerialisable(field))
continue;
// /* Add the Script JSON Object to the JSON root node*/ // Serialise
// rapidjson::Value key(Convert::ToNative(object->GetType()->FullName).c_str(), allocator); writeFieldIntoYaml(field, object, yaml);
// json.AddMember(key.Move(), scriptRoot, allocator); }
// /* Prepare to send to the caller */ yaml << YAML::EndMap;
// // Convert to string }
// rapidjson::StringBuffer buffer; void ReflectionUtilities::Deserialise(YAML::Node& yamlNode, Object^ object)
// rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer); {
// json.Accept(writer); using namespace System::Reflection;
// // Return the result // Load the YAML
// return Convert::ToCLI(std::string(buffer.GetString())); if (!yamlNode.IsMap())
//} {
//void ReflectionUtilities::Deserialise(System::String^ jsonString, Object^ object) // Invalid
//{ Debug::LogError
// // Load the JSON (
// rapidjson::Document json; System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of \"{0}\" script.",
// auto& allocator = json.GetAllocator(); object->GetType()->FullName)
// json.Parse(Convert::ToNative(jsonString).c_str()); );
return;
// // Get the root object }
// auto scriptRoot = json.MemberBegin(); // Get all fields
// if (scriptRoot == json.MemberEnd()) System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
// { for each (FieldInfo^ field in fields)
// Pls::Debug::LogError("[ReflectionUtilities] Attempted read of corrupted serialised object."); {
// return; // Ignore private and non-SerialiseField
// } if (!FieldIsSerialisable(field))
// continue;
// // Get all fields
// IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object); // Deserialise
// for each (FieldInfo^ field in fields) const std::string FIELD_NAME = Convert::ToNative(field->Name);
// { if (yamlNode[FIELD_NAME])
// // Ignore private and non-SerialiseField {
// if (!FieldIsSerialisable(field)) writeYamlIntoField(field, object, yamlNode[FIELD_NAME]);
// continue; }
}
// // Deserialise }
// auto iter = scriptRoot->value.FindMember(Convert::ToNative(field->Name).c_str()); /*---------------------------------------------------------------------------------*/
// if (iter != scriptRoot->value.MemberEnd()) /* Serialization Helper Functions */
// { /*---------------------------------------------------------------------------------*/
// // Get the data and set it in void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml)
// RapidJsonValueToField(iter->value, field, object); {
// Field Name
// } yaml << YAML::Key << Convert::ToNative(fieldInfo->Name);
// }
//} // Field Value
//void ReflectionUtilities::Serialise(Object^ object, JsonWriter& writer) yaml << YAML::Value;
//{ if (fieldInsertYaml<System::Int16> (fieldInfo, object, yaml) ||
// /* Script Name */ fieldInsertYaml<System::Int32> (fieldInfo, object, yaml) ||
// writer.String(Convert::ToNative(object->GetType()->FullName).c_str()); fieldInsertYaml<System::Int64> (fieldInfo, object, yaml) ||
fieldInsertYaml<System::UInt16>(fieldInfo, object, yaml) ||
// /* Script Contents */ fieldInsertYaml<System::UInt32>(fieldInfo, object, yaml) ||
// writer.StartObject(); fieldInsertYaml<System::UInt64>(fieldInfo, object, yaml) ||
// IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object); fieldInsertYaml<System::Byte> (fieldInfo, object, yaml) ||
// for each (FieldInfo^ field in fields) fieldInsertYaml<bool> (fieldInfo, object, yaml) ||
// { fieldInsertYaml<float> (fieldInfo, object, yaml) ||
// // Ignore private and non-SerialiseField fieldInsertYaml<double> (fieldInfo, object, yaml))
// if (!FieldIsSerialisable(field)) {
// continue; return;
}
// // Serialise else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
// serialiseFieldJson(field, object, writer); {
// } yaml << safe_cast<int>(fieldInfo->GetValue(object));
// writer.EndObject(); }
//} else if (fieldInfo->FieldType == System::String::typeid)
{
///*---------------------------------------------------------------------------------*/ System::String^ str = safe_cast<System::String^>(fieldInfo->GetValue(object));
///* Serialisation Helper Functions */ yaml << Convert::ToNative(str);
///*---------------------------------------------------------------------------------*/ }
//rapidjson::Value ReflectionUtilities::FieldToRapidJsonValue(FieldInfo^ fieldInfo, Object^ object, JsonAllocator& allocator) else if (fieldInfo->FieldType == Vector2::typeid)
//{ {
// rapidjson::Value jsonValue; Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq;
// // Check each type of value and convert it into a rapidjson::Value }
// if PRIMITIVE_FIELD_CAST(Int16) else if (fieldInfo->FieldType == Vector3::typeid)
// else if PRIMITIVE_FIELD_CAST(Int32) {
// else if PRIMITIVE_FIELD_CAST(Int64) Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object));
// else if PRIMITIVE_FIELD_CAST(UInt16) yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << vec.z << YAML::EndSeq;
// else if PRIMITIVE_FIELD_CAST(UInt32) }
// else if PRIMITIVE_FIELD_CAST(UInt64) else // Not any of the supported types
// else if PRIMITIVE_FIELD_CAST(Byte) {
// else if PRIMITIVE_FIELD_CAST(bool) Debug::LogWarning(Convert::ToNative(System::String::Format
// else if PRIMITIVE_FIELD_CAST(float) (
// else if PRIMITIVE_FIELD_CAST(double) "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.",
// else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) fieldInfo->Name, fieldInfo->FieldType)
// { ));
// jsonValue = safe_cast<int>(fieldInfo->GetValue(object)); }
// } }
// else if (fieldInfo->FieldType == String::typeid)
// { void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
// String^ str = safe_cast<String^>(fieldInfo->GetValue(object)); {
// jsonValue.SetString(Convert::ToNative(str).c_str(), str->Length, allocator); if (fieldInfo->FieldType == System::Int16::typeid)
// } {
// else if (fieldInfo->FieldType == Vector2::typeid) fieldInfo->SetValue(object, node.as<int>());
// { }
// jsonValue.SetObject(); if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
// Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object)); fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
// jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||
// jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); fieldAssignYaml<System::UInt16>(fieldInfo, object, node) ||
// } fieldAssignYaml<System::UInt32>(fieldInfo, object, node) ||
// else if (fieldInfo->FieldType == Vector3::typeid) fieldAssignYaml<System::UInt64>(fieldInfo, object, node) ||
// { fieldAssignYaml<System::Byte> (fieldInfo, object, node) ||
// jsonValue.SetObject(); fieldAssignYaml<bool> (fieldInfo, object, node) ||
// Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object)); fieldAssignYaml<float> (fieldInfo, object, node) ||
// jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); fieldAssignYaml<double> (fieldInfo, object, node))
// jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); {
// jsonValue.AddMember(rapidjson::Value("z"), rapidjson::Value(vec.z), allocator); return;
// } }
// else if (fieldInfo->FieldType == Color::typeid) else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
// { {
// jsonValue.SetObject(); fieldInfo->SetValue(object, node.as<int>());
// Color col = safe_cast<Color>(fieldInfo->GetValue(object)); }
// jsonValue.AddMember(rapidjson::Value("r"), rapidjson::Value(col.r), allocator); else if (fieldInfo->FieldType == System::String::typeid)
// jsonValue.AddMember(rapidjson::Value("g"), rapidjson::Value(col.g), allocator); {
// jsonValue.AddMember(rapidjson::Value("b"), rapidjson::Value(col.b), allocator); fieldInfo->SetValue(object, Convert::ToCLI(node.as<std::string>()));
// jsonValue.AddMember(rapidjson::Value("a"), rapidjson::Value(col.a), allocator); }
// } else if (fieldInfo->FieldType == Vector2::typeid)
// else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType)) {
// { if (node.IsSequence() && node.size() == 2)
// IResourceID^ rscId = safe_cast<IResourceID^>(fieldInfo->GetValue(object)); {
// jsonValue = rscId->Id; Vector2 vec;
// } vec.x = node[0].as<float>();
// else // Not any of the supported types vec.y = node[1].as<float>();
// { fieldInfo->SetValue(object, vec);
// Pls::Debug::LogWarning(Convert::ToNative(String::Format }
// ( else
// "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.", {
// fieldInfo->Name, fieldInfo->FieldType) Debug::LogWarning
// )); (
// } System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.",
// return jsonValue; fieldInfo->Name, object->GetType()->FullName)
//} );
//void ReflectionUtilities::RapidJsonValueToField(const rapidjson::Value& jsonValue, FieldInfo^ fieldInfo, Object^ object) }
//{ }
// if PRIMITIVE_FIELD_ASSIGN(Int16, GetInt) else if (fieldInfo->FieldType == Vector3::typeid)
// else if PRIMITIVE_FIELD_ASSIGN(Int32, GetInt) {
// else if PRIMITIVE_FIELD_ASSIGN(Int64, GetInt64) if (node.IsSequence() && node.size() == 3)
// else if PRIMITIVE_FIELD_ASSIGN(UInt16, GetUint) {
// else if PRIMITIVE_FIELD_ASSIGN(UInt32, GetUint) Vector3 vec;
// else if PRIMITIVE_FIELD_ASSIGN(UInt64, GetUint64) vec.x = node[0].as<float>();
// else if PRIMITIVE_FIELD_ASSIGN(Byte, GetInt) vec.y = node[1].as<float>();
// else if PRIMITIVE_FIELD_ASSIGN(bool, GetBool) vec.z = node[2].as<float>();
// else if PRIMITIVE_FIELD_ASSIGN(float, GetFloat) fieldInfo->SetValue(object, vec);
// else if PRIMITIVE_FIELD_ASSIGN(double, GetDouble) }
// else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) else
// { {
// fieldInfo->SetValue(object, jsonValue.GetInt()); Debug::LogWarning
// } (
// else if (fieldInfo->FieldType == String::typeid) System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.",
// { fieldInfo->Name, object->GetType()->FullName)
// fieldInfo->SetValue(object, Convert::ToCLI(jsonValue.GetString())); );
// } }
// else if (fieldInfo->FieldType == Vector2::typeid) }
// { else // Not any of the supported types
// Vector2 vec; {
// auto iter = jsonValue.MemberEnd(); Debug::LogWarning(Convert::ToNative(System::String::Format
// PRIMITIVE_VECTOR_FIELD_ASSIGN(x) (
// PRIMITIVE_VECTOR_FIELD_ASSIGN(y) "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.",
// fieldInfo->SetValue(object, vec); fieldInfo->Name, fieldInfo->FieldType)
// } ));
// else if (fieldInfo->FieldType == Vector3::typeid) }
// { }
// Vector3 vec;
// auto iter = jsonValue.MemberEnd();
// PRIMITIVE_VECTOR_FIELD_ASSIGN(x)
// PRIMITIVE_VECTOR_FIELD_ASSIGN(y)
// PRIMITIVE_VECTOR_FIELD_ASSIGN(z)
// fieldInfo->SetValue(object, vec);
// }
// else if (fieldInfo->FieldType == Color::typeid)
// {
// Color col;
// auto iter = jsonValue.MemberEnd();
// PRIMITIVE_COLOR_FIELD_ASSIGN(r)
// PRIMITIVE_COLOR_FIELD_ASSIGN(g)
// PRIMITIVE_COLOR_FIELD_ASSIGN(b)
// PRIMITIVE_COLOR_FIELD_ASSIGN(a)
// fieldInfo->SetValue(object, col);
// }
// else if (IResourceIDInternal::typeid->IsAssignableFrom(fieldInfo->FieldType))
// {
// IResourceIDInternal^ rsc = safe_cast<IResourceIDInternal^>(Activator::CreateInstance(fieldInfo->FieldType));
// rsc->Id = jsonValue.GetInt64();
// fieldInfo->SetValue(object, rsc);
// }
// else // Not any of the supported types
// {
// Pls::Debug::LogWarning(Convert::ToNative(String::Format
// (
// "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.",
// fieldInfo->Name, fieldInfo->FieldType)
// ));
// }
//}
///*---------------------------------------------------------------------------------*/
///* Internal Serialisation Helper Functions */
///*---------------------------------------------------------------------------------*/
//void ReflectionUtilities::serialiseFieldJson(FieldInfo^ fieldInfo, Object^ object, JsonWriter& writer)
//{
// if PRIMITIVE_FIELD_SERIALISE_JSON(Int16, Int)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(Int32, Int)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(Int64, Int64)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt16, Uint)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt32, Uint)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt64, Uint64)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(Byte, Int)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(bool, Bool)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(float, Double)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double)
// else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double)
// else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid))
// {
// PRIMITIVE_WRITE_FIELD_NAME
// writer.Int(safe_cast<Int32>(fieldInfo->GetValue(object)));
// }
// else if (fieldInfo->FieldType == String::typeid)
// {
// PRIMITIVE_WRITE_FIELD_NAME
// writer.String(Convert::ToNative(safe_cast<String^>(fieldInfo->GetValue(object))).c_str());
// }
// else if (fieldInfo->FieldType == Vector2::typeid)
// {
// // Get handle to the Vector to edit
// Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
// // Write the vector data
// PRIMITIVE_WRITE_FIELD_NAME
// writer.StartObject();
// {
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y)
// }
// writer.EndObject();
// }
// else if (fieldInfo->FieldType == Vector3::typeid)
// {
// // Get handle to the Vector to edit
// Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object));
// // Write the vector data
// PRIMITIVE_WRITE_FIELD_NAME
// writer.StartObject();
// {
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(z)
// }
// writer.EndObject();
// }
// else if (fieldInfo->FieldType == Color::typeid)
// {
// // Get handle to the Vector to edit
// Color vec = safe_cast<Color>(fieldInfo->GetValue(object));
// // Write the vector data
// PRIMITIVE_WRITE_FIELD_NAME
// writer.StartObject();
// {
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(r)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(g)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(b)
// PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(a)
// }
// writer.EndObject();
// }
// else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType))
// {
// PRIMITIVE_WRITE_FIELD_NAME
// IResourceID^ rsc = safe_cast<IResourceID^>(fieldInfo->GetValue(object));
// writer.Int64(rsc->Id);
// }
// else // Not any of the supported types
// {
// Pls::Debug::LogWarning(Convert::ToNative(String::Format
// (
// "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.",
// fieldInfo->Name, fieldInfo->FieldType)
// ));
// }
//}
} }

View File

@ -0,0 +1,54 @@
/************************************************************************************//*!
\file ReflectionUtilities.h++
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 16, 2022
\brief Contains the definition of the template functions of the managed
ReflectionUtilities static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Primary Header
#include "ReflectionUtilities.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Serialization Helper Functions */
/*---------------------------------------------------------------------------------*/
template<typename FieldType>
bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter)
{
if (fieldInfo->FieldType == FieldType::typeid)
{
emitter << safe_cast<FieldType>(fieldInfo->GetValue(object));
return true;
}
return false;
}
template<typename FieldType>
bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
{
return fieldAssignYaml<FieldType, FieldType>(fieldInfo, object, node);
}
template<typename FieldType, typename CastType>
bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
{
if (fieldInfo->FieldType == FieldType::typeid)
{
fieldInfo->SetValue(object, node.as<CastType>());
return true;
}
return false;
}
}

View File

@ -14,9 +14,7 @@ of DigiPen Institute of Technology is prohibited.
#pragma once #pragma once
// External Dependencies // External Dependencies
#include <yaml-cpp/node/node.h> #include <yaml-cpp/yaml.h>
#include <yaml-cpp/emitter.h>
namespace SHADE namespace SHADE
{ {
@ -26,10 +24,6 @@ namespace SHADE
private ref class ReflectionUtilities abstract sealed private ref class ReflectionUtilities abstract sealed
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Utility Functions */ /* Utility Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -58,16 +52,30 @@ namespace SHADE
/// attribute will be serialised. /// attribute will be serialised.
/// </summary> /// </summary>
/// <param name="object">The object to serialise.</param> /// <param name="object">The object to serialise.</param>
//static void Serialise(Object^ object, YAML::Emitter& yaml); static void Serialise(System::Object^ object, YAML::Emitter& yaml);
/// <summary> /// <summary>
/// Deserialises a JSON string and copies the deserialised data into the /// Deserialises a YAML node that contains a map of Scripts and copies the
/// specified object if there are matching fields. /// deserialised data into the specified object if there are matching fields.
/// </summary> /// </summary>
/// <param name="jsonString"> /// <param name="yamlNode">
/// The JSON string that contains the data to copy into this PlushieScript /// The JSON string that contains the data to copy into this PlushieScript
/// object. /// object.
/// </param> /// </param>
/// <param name="object">The object to copy deserialised data into.</param> /// <param name="object">The object to copy deserialised data into.</param>
//static void Deserialise(System::String^ jsonString, Object^ object); static void Deserialise(YAML::Node& yamlNode, Object^ object);
/*-----------------------------------------------------------------------------*/
/* Serialization Helper Functions */
/*-----------------------------------------------------------------------------*/
static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml);
template<typename FieldType>
static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter);
static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
template<typename FieldType>
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
template<typename FieldType, typename CastType>
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
}; };
} }
#include "ReflectionUtilities.h++"