Reworked script serialization and deserialization functions (WIP)

This commit is contained in:
Kah Wei 2022-10-19 20:43:22 +08:00
parent 2dcf367bc5
commit 4f177bc455
10 changed files with 145 additions and 140 deletions

View File

@ -37,7 +37,8 @@ project "SHADE_Application"
"%{IncludeDir.VULKAN}/include", "%{IncludeDir.VULKAN}/include",
"%{IncludeDir.spdlog}/include", "%{IncludeDir.spdlog}/include",
"%{IncludeDir.tinyddsloader}", "%{IncludeDir.tinyddsloader}",
"%{IncludeDir.reactphysics3d}\\include" "%{IncludeDir.reactphysics3d}\\include",
"%{IncludeDir.yamlcpp}"
} }
externalwarnings "Off" externalwarnings "Off"
@ -51,6 +52,7 @@ project "SHADE_Application"
{ {
"SHADE_Engine", "SHADE_Engine",
"SHADE_Managed", "SHADE_Managed",
"yaml-cpp",
"SDL2.lib", "SDL2.lib",
"SDL2main.lib" "SDL2main.lib"
} }

View File

@ -115,34 +115,22 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
std::string SHScriptEngine::SerialiseScripts(EntityID entity) const bool SHScriptEngine::SerialiseScripts(EntityID entity, YAML::Node& scriptsNode) const
{ {
// Create buffer needed to store serialised script data
constexpr int BUFFER_SIZE = 10240;
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
std::memset(buffer.get(), 0, BUFFER_SIZE);
// Attempt to serialise the script // Attempt to serialise the script
std::string result; if (csScriptsSerialiseYaml(entity, &scriptsNode))
if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE)) return true;
{
result = std::string(buffer.get());
}
else
{
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
}
// Return an empty string since we failed to serialise SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts for entity #{}.", entity);
return result; return false;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const bool SHScriptEngine::DeserialiseScript(EntityID entity, YAML::Node& scriptsNode) const
{ {
csScriptDeserialise(entity, yaml.c_str()); return csScriptsDeserialiseYaml(entity, &scriptsNode);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -380,30 +368,18 @@ namespace SHADE
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"RemoveAllScriptsImmediately" "RemoveAllScriptsImmediately"
); );
/*csScriptsSerialise = dotNet.GetFunctionPtr<CsScriptSerialiseFuncPtr> csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScripts" "SerialiseScripts"
); );
csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr> csScriptsDeserialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScriptsYaml" "DeserialiseScripts"
); );
csScriptDeserialise = dotNet.GetFunctionPtr<CsScriptDeserialiseFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"DeserialiseScript"
);
csScriptDeserialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScriptsYaml"
);*/
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,

View File

@ -13,7 +13,8 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <filesystem> #include <filesystem>
// External Dependencies
#include <yaml-cpp/yaml.h>
// Project Headers // Project Headers
#include "SH_API.h" #include "SH_API.h"
#include "SHDotNetRuntime.h" #include "SHDotNetRuntime.h"
@ -141,23 +142,26 @@ namespace SHADE
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Generates a JSON string that represents the set of Scripts attached to the /// Performs serialization of all scripts for the specified entity into the
/// specified Entity. /// YAML::Node specified. This node will contain all serialised scripts after
/// calling this function.
/// </summary> /// </summary>
/// <param name="entity"> The Entity to Serialise.</param> /// <param name="entity">The Entity to Serialise.</param>
/// <returns> /// <param name="scriptsNode">
/// String that represents the set of scripts attached to the specified Entity. /// YAML Node that will store the serialised scripts.
/// </returns> /// </param>
std::string SerialiseScripts(EntityID entity) const; /// <return>True if successfully serialised.</return>
bool SerialiseScripts(EntityID entity, YAML::Node& scriptsNode) const;
/// <summary> /// <summary>
/// Loads the specified JSON string and creates a Script for the specified Entity /// Creates scripts and sets fields for the specified Entity based on the specified
/// based on the specified JSON string. /// YAML node.
/// </summary> /// </summary>
/// <param name="entity">The Entity to deserialise a Script on to.</param> /// <param name="entity">The Entity to deserialise a Script on to.</param>
/// <param name="yaml"> /// <param name="scriptsNode">
/// The YAML string that represents the Script to load into the Entity. /// YAML Node that contains the serialised script data.
/// </param> /// </param>
void DeserialiseScript(EntityID entity, const std::string& yaml) const; /// <return>True if successfully deserialised.</return>
bool DeserialiseScript(EntityID entity, YAML::Node& scriptsNode) const;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Script Editor Functions */ /* Script Editor Functions */
@ -211,8 +215,7 @@ namespace SHADE
using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); using CsScriptManipFuncPtr = bool(*)(EntityID, const char*);
using CsScriptBasicFuncPtr = void(*)(EntityID); using CsScriptBasicFuncPtr = void(*)(EntityID);
using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); using CsScriptOptionalFuncPtr = void(*)(EntityID, bool);
using CsScriptSerialiseFuncPtr = bool(*)(EntityID, char*, int); using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*);
using CsScriptDeserialiseFuncPtr = bool(*)(EntityID, const char*);
using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*);
using CsScriptEditorFuncPtr = void(*)(EntityID); using CsScriptEditorFuncPtr = void(*)(EntityID);
@ -245,10 +248,8 @@ namespace SHADE
CsScriptManipFuncPtr csScriptsAdd = nullptr; CsScriptManipFuncPtr csScriptsAdd = nullptr;
CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr;
CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr;
CsScriptSerialiseFuncPtr csScriptsSerialise = nullptr;
CsScriptDeserialiseFuncPtr csScriptDeserialise = nullptr;
CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr;
CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr;
// - Editor // - Editor
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
CsFuncPtr csEditorUndo = nullptr; CsFuncPtr csEditorUndo = nullptr;

View File

@ -13,6 +13,8 @@
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHRigidBodyComponent.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE namespace SHADE
{ {
@ -157,7 +159,7 @@ namespace SHADE
node = YAML::Null; node = YAML::Null;
return node; return node;
} }
node.SetStyle(YAML::EmitterStyle::Block); node.SetStyle(YAML::EmitterStyle::Block);
node[EIDNode] = eid; node[EIDNode] = eid;
node[EntityNameNode] = entity->name; node[EntityNameNode] = entity->name;
node[IsActiveNode] = sceneNode->IsActive(); node[IsActiveNode] = sceneNode->IsActive();
@ -179,6 +181,14 @@ namespace SHADE
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody); components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
} }
node[ComponentsNode] = components; node[ComponentsNode] = components;
YAML::Node scripts;
SHSystemManager::GetSystem<SHScriptEngine>()->SerialiseScripts(eid, scripts);
node[ScriptsNode] = scripts;
//YAML::Emitter emitter;
//emitter << node;
//SHLOG_TRACE(emitter.c_str())
return node; return node;
} }

View File

@ -21,6 +21,7 @@ namespace SHADE
constexpr const char* EIDNode = "EID"; constexpr const char* EIDNode = "EID";
constexpr const char* IsActiveNode = "IsActive"; constexpr const char* IsActiveNode = "IsActive";
constexpr const char* NumberOfChildrenNode = "NumberOfChildren"; constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
constexpr const char* ScriptsNode = "Scripts";
struct SH_API SHSerialization struct SH_API SHSerialization
{ {

View File

@ -26,6 +26,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Script.hxx" #include "Script.hxx"
#include "Engine/Entity.hxx" #include "Engine/Entity.hxx"
#include "Serialisation/ReflectionUtilities.hxx"
namespace SHADE namespace SHADE
{ {
@ -470,70 +471,78 @@ namespace SHADE
} }
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
} }
bool ScriptStore::SerialiseScripts(Entity entity, System::Text::StringBuilder^ buffer, int bufferSize)
bool ScriptStore::SerialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Create a buffer that we can work with temporarily // Convert to pointer
System::Text::StringBuilder^ jsonString = gcnew System::Text::StringBuilder(); YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer());
// Check if yamlNode is valid
if (yamlNode == nullptr)
{
Debug::LogWarning("Attempted to serialise scripts with an invalid YAML Node! Skipping.");
return false;
}
// Check if entity exists, otherwise nothing // Check if entity exists, otherwise nothing
if (!EntityUtils::IsValid(entity)) if (!EntityUtils::IsValid(entity))
return true; {
Debug::LogWarning("Attempted to serialise scripts for an invalid Entity! Skipping.");
return false;
}
// Check if entity exists in the script storage // Check if entity exists in the script storage
if (!scripts.ContainsKey(entity)) if (!scripts.ContainsKey(entity))
return true; return true;
// Serialise each script // Serialise each script
//yamlNode->SetStyle(YAML::EmitterStyle::Block);
System::Collections::Generic::List<Script^>^ scriptList = scripts[entity]; System::Collections::Generic::List<Script^>^ scriptList = scripts[entity];
for (int i = 0; i < scriptList->Count; ++i) for each (Script^ script in scriptList)
{ {
throw gcnew System::NotImplementedException; ReflectionUtilities::Serialise(script, *yamlNode);
//jsonString->Append(ReflectionUtilities::Serialise(scriptList[i]));
// Only add separator if is not last script
if (i != scriptList->Count - 1)
{
jsonString->Append(",\r\n");
}
} }
// Check if the size is too big
if (jsonString->Length > bufferSize)
return false;
// Otherwise we copy it over
buffer->Clear();
buffer->Append(jsonString->ToString());
return true; return true;
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
return false; return false;
} }
bool ScriptStore::DeserialiseScript(Entity entity, System::String^ yaml) bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Convert to pointer
YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer());
// Check if yamlNode is valid
if (yamlNode == nullptr)
{
Debug::LogWarning("Attempted to deserialise scripts with an invalid YAML Node! Skipping.");
return false;
}
// Check if entity exists, otherwise nothing // Check if entity exists, otherwise nothing
if (!EntityUtils::IsValid(entity)) if (!EntityUtils::IsValid(entity))
return false;
// Get the name of the script
const int FIRST_QUOTE = yaml->IndexOf('\"');
const int FIRST_COLON = yaml->IndexOf(':');
if (FIRST_QUOTE < 0 || FIRST_COLON < 0) // No script name, it's invalid
return false;
const int SCRIPT_NAME_START = FIRST_QUOTE + 1;
const int SCRIPT_NAME_END = FIRST_COLON - 1;
System::String^ typeName = yaml->Substring(SCRIPT_NAME_START, SCRIPT_NAME_END - SCRIPT_NAME_START);
// Create the script
Script^ script;
if (AddScriptViaNameWithRef(entity, typeName, script))
{ {
// Copy the data in Debug::LogWarning("Attempted to deserialise scripts for an invalid Entity! Skipping.");
throw gcnew System::NotImplementedException; return false;
//ReflectionUtilities::Deserialise(json, script); }
return true;
// Go through all elements in the node
for (YAML::Node& node : *yamlNode)
{
// Get the name of the script
const std::string typeName = ""; // TODO
// Create
Script^ script;
if (AddScriptViaNameWithRef(entity, Convert::ToCLI(typeName), script))
{
// Copy the data in
ReflectionUtilities::Deserialise(script, node);
return true;
}
} }
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")

View File

@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "Engine/Entity.hxx" #include "Engine/Entity.hxx"
#include "Script.hxx" #include "Script.hxx"
#include "Serialization/SHSerialization.h"
namespace SHADE namespace SHADE
{ {
@ -237,27 +238,23 @@ namespace SHADE
/* Serialisation Functions */ /* Serialisation Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Generates a JSON string that represents the set of Scripts attached /// Populates a YAML node with the scripts for a specified Entity.
/// to the specified Entity.
/// <br/> <br/> /// <br/> <br/>
/// This function should only be called from native unmanaged code. /// This function should only be called from native unmanaged code.
/// </summary> /// </summary>
/// <param name="entity">The Entity to Serialise.</param> /// <param name="entity">The Entity to Serialise.</param>
/// <param name="buffer"> /// <param name="yamlNode">
/// StringBuilder handle that maps to a native char array that will contain the /// Pointer to a YAML::Node that will be populated with all of the serialised
/// serialised string. /// scripts and their associated fields.
/// </param>
/// <param name="bufferSize">
/// The size of the char array.
/// </param> /// </param>
/// <returns> /// <returns>
/// True if serialisation is successful. False if the buffer is too small for /// True if serialisation is successful. False if the buffer is too small for
/// the serialised output. /// the serialised output.
/// </returns> /// </returns>
static bool SerialiseScripts(Entity entity, System::Text::StringBuilder^ buffer, int bufferSize); static bool SerialiseScripts(Entity entity, System::IntPtr yamlNode);
/// <summary> /// <summary>
/// Processes a JSON string that represents a single Script and attaches /// Processes a YAML node that contains a list of multiple scripts to be loaded
/// it onto the specified Entity. /// into the specified Entity.
/// <br/> <br/> /// <br/> <br/>
/// This function should only be called from native unmanaged code. /// This function should only be called from native unmanaged code.
/// </summary> /// </summary>
@ -265,10 +262,10 @@ namespace SHADE
/// The Entity to attach the deserialised Scripts to. /// The Entity to attach the deserialised Scripts to.
/// </param> /// </param>
/// <param name="yaml"> /// <param name="yaml">
/// JSON string that describes the Script to serialise. /// Pointer to the YAML::Node that contains serialized script data.
/// </param> /// </param>
/// <returns></returns> /// <returns></returns>
static bool DeserialiseScript(Entity entity, System::String^ yaml); static bool DeserialiseScripts(Entity entity, System::IntPtr yamlNode);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -61,13 +61,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Serialisation Functions */ /* Serialisation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) void ReflectionUtilities::Serialise(System::Object^ object, YAML::Node& yamlNode)
{ {
using namespace System::Reflection; using namespace System::Reflection;
// Create YAML object // Create YAML object
yaml << YAML::Key << Convert::ToNative(object->GetType()->FullName); YAML::Node scriptNode;
yaml << YAML::BeginMap;
// Get all fields // Get all fields
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object); System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
@ -78,12 +77,12 @@ namespace SHADE
continue; continue;
// Serialise // Serialise
writeFieldIntoYaml(field, object, yaml); writeFieldIntoYaml(field, object, scriptNode);
} }
yaml << YAML::EndMap; yamlNode[Convert::ToNative(object->GetType()->FullName)] = scriptNode;
} }
void ReflectionUtilities::Deserialise(YAML::Node& yamlNode, Object^ object) void ReflectionUtilities::Deserialise(Object^ object, YAML::Node& yamlNode)
{ {
using namespace System::Reflection; using namespace System::Reflection;
@ -117,44 +116,50 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Serialization Helper Functions */ /* Serialization Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml) void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& yamlNode)
{ {
// Field Name // Field YAML Node
yaml << YAML::Key << Convert::ToNative(fieldInfo->Name); YAML::Node fieldNode;
fieldNode.SetStyle(YAML::EmitterStyle::Block);
// Field Value fieldNode["Name"] = Convert::ToNative(fieldInfo->Name);
yaml << YAML::Value;
if (fieldInsertYaml<System::Int16> (fieldInfo, object, yaml) || // Retrieve string for the YAML
fieldInsertYaml<System::Int32> (fieldInfo, object, yaml) || if (fieldInsertYaml<System::Int16> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<System::Int64> (fieldInfo, object, yaml) || fieldInsertYaml<System::Int32> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<System::UInt16>(fieldInfo, object, yaml) || fieldInsertYaml<System::Int64> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<System::UInt32>(fieldInfo, object, yaml) || fieldInsertYaml<System::UInt16>(fieldInfo, object, fieldNode) ||
fieldInsertYaml<System::UInt64>(fieldInfo, object, yaml) || fieldInsertYaml<System::UInt32>(fieldInfo, object, fieldNode) ||
fieldInsertYaml<System::Byte> (fieldInfo, object, yaml) || fieldInsertYaml<System::UInt64>(fieldInfo, object, fieldNode) ||
fieldInsertYaml<bool> (fieldInfo, object, yaml) || fieldInsertYaml<System::Byte> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<float> (fieldInfo, object, yaml) || fieldInsertYaml<bool> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<double> (fieldInfo, object, yaml)) fieldInsertYaml<float> (fieldInfo, object, fieldNode) ||
fieldInsertYaml<double> (fieldInfo, object, fieldNode))
{ {
return; return;
} }
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
{ {
yaml << safe_cast<int>(fieldInfo->GetValue(object)); fieldNode = std::to_string(safe_cast<int>(fieldInfo->GetValue(object)));
} }
else if (fieldInfo->FieldType == System::String::typeid) else if (fieldInfo->FieldType == System::String::typeid)
{ {
System::String^ str = safe_cast<System::String^>(fieldInfo->GetValue(object)); System::String^ str = safe_cast<System::String^>(fieldInfo->GetValue(object));
yaml << Convert::ToNative(str); fieldNode = Convert::ToNative(str);
} }
else if (fieldInfo->FieldType == Vector2::typeid) else if (fieldInfo->FieldType == Vector2::typeid)
{ {
Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object)); Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq; fieldNode.SetStyle(YAML::EmitterStyle::Flow);
fieldNode.push_back(vec.x);
fieldNode.push_back(vec.y);
} }
else if (fieldInfo->FieldType == Vector3::typeid) else if (fieldInfo->FieldType == Vector3::typeid)
{ {
Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object)); Vector3 vec = safe_cast<Vector3>(fieldInfo->GetValue(object));
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << vec.z << YAML::EndSeq; fieldNode.SetStyle(YAML::EmitterStyle::Flow);
fieldNode.push_back(vec.x);
fieldNode.push_back(vec.y);
fieldNode.push_back(vec.z);
} }
else // Not any of the supported types else // Not any of the supported types
{ {
@ -163,7 +168,11 @@ namespace SHADE
"[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.", "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.",
fieldInfo->Name, fieldInfo->FieldType) fieldInfo->Name, fieldInfo->FieldType)
)); ));
return;
} }
// Store the field into YAML
yamlNode.push_back(fieldNode);
} }
void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)

View File

@ -23,11 +23,11 @@ namespace SHADE
/* Serialization Helper Functions */ /* Serialization Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template<typename FieldType> template<typename FieldType>
bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter) bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode)
{ {
if (fieldInfo->FieldType == FieldType::typeid) if (fieldInfo->FieldType == FieldType::typeid)
{ {
emitter << safe_cast<FieldType>(fieldInfo->GetValue(object)); fieldNode = 0.0;//static_cast<double>(safe_cast<FieldType>(fieldInfo->GetValue(object)));
return true; return true;
} }

View File

@ -52,7 +52,7 @@ 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(System::Object^ object, YAML::Emitter& yaml); static void Serialise(System::Object^ object, YAML::Node& yamlNode);
/// <summary> /// <summary>
/// Deserialises a YAML node that contains a map of Scripts and copies the /// Deserialises a YAML node that contains a map of Scripts and copies the
/// deserialised data into the specified object if there are matching fields. /// deserialised data into the specified object if there are matching fields.
@ -62,14 +62,14 @@ namespace SHADE
/// 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(YAML::Node& yamlNode, Object^ object); static void Deserialise(System::Object^ object, YAML::Node& yamlNode);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Serialization Helper Functions */ /* Serialization Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml); static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& yamlNode);
template<typename FieldType> template<typename FieldType>
static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter); static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode);
static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
template<typename FieldType> template<typename FieldType>
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);