Added YAML serialization of scripts
This commit is contained in:
parent
c89fe48182
commit
4546b84c06
|
@ -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 all fields
|
||||||
|
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
|
||||||
|
for each (FieldInfo^ field in fields)
|
||||||
|
{
|
||||||
|
// Ignore private and non-SerialiseField
|
||||||
|
if (!FieldIsSerialisable(field))
|
||||||
|
continue;
|
||||||
|
|
||||||
// // Get the root object
|
// Deserialise
|
||||||
// auto scriptRoot = json.MemberBegin();
|
const std::string FIELD_NAME = Convert::ToNative(field->Name);
|
||||||
// if (scriptRoot == json.MemberEnd())
|
if (yamlNode[FIELD_NAME])
|
||||||
// {
|
{
|
||||||
// Pls::Debug::LogError("[ReflectionUtilities] Attempted read of corrupted serialised object.");
|
writeYamlIntoField(field, object, yamlNode[FIELD_NAME]);
|
||||||
// return;
|
}
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// // Get all fields
|
/*---------------------------------------------------------------------------------*/
|
||||||
// IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
|
/* Serialization Helper Functions */
|
||||||
// for each (FieldInfo^ field in fields)
|
/*---------------------------------------------------------------------------------*/
|
||||||
// {
|
void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml)
|
||||||
// // Ignore private and non-SerialiseField
|
{
|
||||||
// if (!FieldIsSerialisable(field))
|
// Field Name
|
||||||
// continue;
|
yaml << YAML::Key << Convert::ToNative(fieldInfo->Name);
|
||||||
|
|
||||||
// // Deserialise
|
// Field Value
|
||||||
// auto iter = scriptRoot->value.FindMember(Convert::ToNative(field->Name).c_str());
|
yaml << YAML::Value;
|
||||||
// if (iter != scriptRoot->value.MemberEnd())
|
if (fieldInsertYaml<System::Int16> (fieldInfo, object, yaml) ||
|
||||||
// {
|
fieldInsertYaml<System::Int32> (fieldInfo, object, yaml) ||
|
||||||
// // Get the data and set it in
|
fieldInsertYaml<System::Int64> (fieldInfo, object, yaml) ||
|
||||||
// RapidJsonValueToField(iter->value, field, object);
|
fieldInsertYaml<System::UInt16>(fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<System::UInt32>(fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<System::UInt64>(fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<System::Byte> (fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<bool> (fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<float> (fieldInfo, object, yaml) ||
|
||||||
|
fieldInsertYaml<double> (fieldInfo, object, yaml))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
|
||||||
|
{
|
||||||
|
yaml << safe_cast<int>(fieldInfo->GetValue(object));
|
||||||
|
}
|
||||||
|
else if (fieldInfo->FieldType == System::String::typeid)
|
||||||
|
{
|
||||||
|
System::String^ str = safe_cast<System::String^>(fieldInfo->GetValue(object));
|
||||||
|
yaml << Convert::ToNative(str);
|
||||||
|
}
|
||||||
|
else if (fieldInfo->FieldType == Vector2::typeid)
|
||||||
|
{
|
||||||
|
Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
|
||||||
|
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq;
|
||||||
|
}
|
||||||
|
else if (fieldInfo->FieldType == Vector3::typeid)
|
||||||
|
{
|
||||||
|
Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object));
|
||||||
|
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << vec.z << YAML::EndSeq;
|
||||||
|
}
|
||||||
|
else // Not any of the supported types
|
||||||
|
{
|
||||||
|
Debug::LogWarning(Convert::ToNative(System::String::Format
|
||||||
|
(
|
||||||
|
"[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.",
|
||||||
|
fieldInfo->Name, fieldInfo->FieldType)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||||
// }
|
{
|
||||||
//}
|
if (fieldInfo->FieldType == System::Int16::typeid)
|
||||||
//void ReflectionUtilities::Serialise(Object^ object, JsonWriter& writer)
|
{
|
||||||
//{
|
fieldInfo->SetValue(object, node.as<int>());
|
||||||
// /* Script Name */
|
}
|
||||||
// writer.String(Convert::ToNative(object->GetType()->FullName).c_str());
|
if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
|
||||||
// /* Script Contents */
|
fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||
|
||||||
// writer.StartObject();
|
fieldAssignYaml<System::UInt16>(fieldInfo, object, node) ||
|
||||||
// IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
|
fieldAssignYaml<System::UInt32>(fieldInfo, object, node) ||
|
||||||
// for each (FieldInfo^ field in fields)
|
fieldAssignYaml<System::UInt64>(fieldInfo, object, node) ||
|
||||||
// {
|
fieldAssignYaml<System::Byte> (fieldInfo, object, node) ||
|
||||||
// // Ignore private and non-SerialiseField
|
fieldAssignYaml<bool> (fieldInfo, object, node) ||
|
||||||
// if (!FieldIsSerialisable(field))
|
fieldAssignYaml<float> (fieldInfo, object, node) ||
|
||||||
// continue;
|
fieldAssignYaml<double> (fieldInfo, object, node))
|
||||||
|
{
|
||||||
// // Serialise
|
return;
|
||||||
// serialiseFieldJson(field, object, writer);
|
}
|
||||||
// }
|
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
|
||||||
// writer.EndObject();
|
{
|
||||||
//}
|
fieldInfo->SetValue(object, node.as<int>());
|
||||||
|
}
|
||||||
///*---------------------------------------------------------------------------------*/
|
else if (fieldInfo->FieldType == System::String::typeid)
|
||||||
///* Serialisation Helper Functions */
|
{
|
||||||
///*---------------------------------------------------------------------------------*/
|
fieldInfo->SetValue(object, Convert::ToCLI(node.as<std::string>()));
|
||||||
//rapidjson::Value ReflectionUtilities::FieldToRapidJsonValue(FieldInfo^ fieldInfo, Object^ object, JsonAllocator& allocator)
|
}
|
||||||
//{
|
else if (fieldInfo->FieldType == Vector2::typeid)
|
||||||
// rapidjson::Value jsonValue;
|
{
|
||||||
|
if (node.IsSequence() && node.size() == 2)
|
||||||
// // Check each type of value and convert it into a rapidjson::Value
|
{
|
||||||
// if PRIMITIVE_FIELD_CAST(Int16)
|
Vector2 vec;
|
||||||
// else if PRIMITIVE_FIELD_CAST(Int32)
|
vec.x = node[0].as<float>();
|
||||||
// else if PRIMITIVE_FIELD_CAST(Int64)
|
vec.y = node[1].as<float>();
|
||||||
// else if PRIMITIVE_FIELD_CAST(UInt16)
|
fieldInfo->SetValue(object, vec);
|
||||||
// else if PRIMITIVE_FIELD_CAST(UInt32)
|
}
|
||||||
// else if PRIMITIVE_FIELD_CAST(UInt64)
|
else
|
||||||
// else if PRIMITIVE_FIELD_CAST(Byte)
|
{
|
||||||
// else if PRIMITIVE_FIELD_CAST(bool)
|
Debug::LogWarning
|
||||||
// else if PRIMITIVE_FIELD_CAST(float)
|
(
|
||||||
// else if PRIMITIVE_FIELD_CAST(double)
|
System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.",
|
||||||
// else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid))
|
fieldInfo->Name, object->GetType()->FullName)
|
||||||
// {
|
);
|
||||||
// jsonValue = safe_cast<int>(fieldInfo->GetValue(object));
|
}
|
||||||
// }
|
}
|
||||||
// else if (fieldInfo->FieldType == String::typeid)
|
else if (fieldInfo->FieldType == Vector3::typeid)
|
||||||
// {
|
{
|
||||||
// String^ str = safe_cast<String^>(fieldInfo->GetValue(object));
|
if (node.IsSequence() && node.size() == 3)
|
||||||
// jsonValue.SetString(Convert::ToNative(str).c_str(), str->Length, allocator);
|
{
|
||||||
// }
|
Vector3 vec;
|
||||||
// else if (fieldInfo->FieldType == Vector2::typeid)
|
vec.x = node[0].as<float>();
|
||||||
// {
|
vec.y = node[1].as<float>();
|
||||||
// jsonValue.SetObject();
|
vec.z = node[2].as<float>();
|
||||||
// Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
|
fieldInfo->SetValue(object, vec);
|
||||||
// jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator);
|
}
|
||||||
// jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator);
|
else
|
||||||
// }
|
{
|
||||||
// else if (fieldInfo->FieldType == Vector3::typeid)
|
Debug::LogWarning
|
||||||
// {
|
(
|
||||||
// jsonValue.SetObject();
|
System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.",
|
||||||
// Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object));
|
fieldInfo->Name, object->GetType()->FullName)
|
||||||
// jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator);
|
);
|
||||||
// jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator);
|
}
|
||||||
// jsonValue.AddMember(rapidjson::Value("z"), rapidjson::Value(vec.z), allocator);
|
}
|
||||||
// }
|
else // Not any of the supported types
|
||||||
// else if (fieldInfo->FieldType == Color::typeid)
|
{
|
||||||
// {
|
Debug::LogWarning(Convert::ToNative(System::String::Format
|
||||||
// jsonValue.SetObject();
|
(
|
||||||
// Color col = safe_cast<Color>(fieldInfo->GetValue(object));
|
"[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.",
|
||||||
// jsonValue.AddMember(rapidjson::Value("r"), rapidjson::Value(col.r), allocator);
|
fieldInfo->Name, fieldInfo->FieldType)
|
||||||
// jsonValue.AddMember(rapidjson::Value("g"), rapidjson::Value(col.g), allocator);
|
));
|
||||||
// jsonValue.AddMember(rapidjson::Value("b"), rapidjson::Value(col.b), allocator);
|
}
|
||||||
// jsonValue.AddMember(rapidjson::Value("a"), rapidjson::Value(col.a), allocator);
|
}
|
||||||
// }
|
|
||||||
// else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType))
|
|
||||||
// {
|
|
||||||
// IResourceID^ rscId = safe_cast<IResourceID^>(fieldInfo->GetValue(object));
|
|
||||||
// jsonValue = rscId->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)
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
// return jsonValue;
|
|
||||||
//}
|
|
||||||
//void ReflectionUtilities::RapidJsonValueToField(const rapidjson::Value& jsonValue, FieldInfo^ fieldInfo, Object^ object)
|
|
||||||
//{
|
|
||||||
// if PRIMITIVE_FIELD_ASSIGN(Int16, GetInt)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(Int32, GetInt)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(Int64, GetInt64)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(UInt16, GetUint)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(UInt32, GetUint)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(UInt64, GetUint64)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(Byte, GetInt)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(bool, GetBool)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(float, GetFloat)
|
|
||||||
// else if PRIMITIVE_FIELD_ASSIGN(double, GetDouble)
|
|
||||||
// else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid))
|
|
||||||
// {
|
|
||||||
// fieldInfo->SetValue(object, jsonValue.GetInt());
|
|
||||||
// }
|
|
||||||
// else if (fieldInfo->FieldType == String::typeid)
|
|
||||||
// {
|
|
||||||
// fieldInfo->SetValue(object, Convert::ToCLI(jsonValue.GetString()));
|
|
||||||
// }
|
|
||||||
// else if (fieldInfo->FieldType == Vector2::typeid)
|
|
||||||
// {
|
|
||||||
// Vector2 vec;
|
|
||||||
// auto iter = jsonValue.MemberEnd();
|
|
||||||
// PRIMITIVE_VECTOR_FIELD_ASSIGN(x)
|
|
||||||
// PRIMITIVE_VECTOR_FIELD_ASSIGN(y)
|
|
||||||
// fieldInfo->SetValue(object, vec);
|
|
||||||
// }
|
|
||||||
// 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)
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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++"
|
Loading…
Reference in New Issue