From 166a036142bfad809663775c107d5e686449d79f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 20 Oct 2022 11:08:20 +0800 Subject: [PATCH] Completed script serialization in YAML --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 4 +- SHADE_Engine/src/Scripting/SHScriptEngine.h | 54 ++++++++-------- .../src/Serialization/SHSerialization.cpp | 7 +- SHADE_Managed/src/Scripts/ScriptStore.cxx | 24 +++++-- .../src/Serialisation/ReflectionUtilities.h++ | 5 +- .../src/Serialisation/ReflectionUtilities.hxx | 1 - SHADE_Managed/src/Utility/Convert.hxx | 64 +++++++++++++++++++ 7 files changed, 117 insertions(+), 42 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 6585414d..fea59353 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -128,7 +128,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*-----------------------------------------------------------------------------------*/ - bool SHScriptEngine::DeserialiseScript(EntityID entity, YAML::Node& scriptsNode) const + bool SHScriptEngine::DeserialiseScripts(EntityID entity, const YAML::Node& scriptsNode) const { return csScriptsDeserialiseYaml(entity, &scriptsNode); } @@ -374,7 +374,7 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "SerialiseScripts" ); - csScriptsDeserialiseYaml = dotNet.GetFunctionPtr + csScriptsDeserialiseYaml = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 58dbe0b3..137d978f 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -161,7 +161,7 @@ namespace SHADE /// YAML Node that contains the serialised script data. /// /// True if successfully deserialised. - bool DeserialiseScript(EntityID entity, YAML::Node& scriptsNode) const; + bool DeserialiseScripts(EntityID entity, const YAML::Node& scriptsNode) const; /*-----------------------------------------------------------------------------*/ /* Script Editor Functions */ @@ -211,13 +211,13 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using CsFuncPtr = void(*)(void); - using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); - using CsScriptBasicFuncPtr = void(*)(EntityID); - using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); - using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); - using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); - using CsScriptEditorFuncPtr = void(*)(EntityID); + using CsFuncPtr = void(*)(void); + using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); + using CsScriptBasicFuncPtr = void(*)(EntityID); + using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); + using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); + using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); + using CsScriptEditorFuncPtr = void(*)(EntityID); /*-----------------------------------------------------------------------------*/ /* Constants */ @@ -231,29 +231,29 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - SHDotNetRuntime dotNet { false }; + SHDotNetRuntime dotNet { false }; // Function Pointers to CLR Code // - Engine Lifecycle - CsFuncPtr csEngineInit = nullptr; - CsFuncPtr csEngineLoadScripts = nullptr; - CsFuncPtr csEngineUnloadScripts = nullptr; - CsFuncPtr csEngineReloadScripts = nullptr; - CsFuncPtr csEngineExit = nullptr; + CsFuncPtr csEngineInit = nullptr; + CsFuncPtr csEngineLoadScripts = nullptr; + CsFuncPtr csEngineUnloadScripts = nullptr; + CsFuncPtr csEngineReloadScripts = nullptr; + CsFuncPtr csEngineExit = nullptr; // - Scripts Store - CsFuncPtr csScriptsFrameSetUp = nullptr; - CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; - CsFuncPtr csScriptsExecuteUpdate = nullptr; - CsFuncPtr csScriptsExecuteLateUpdate = nullptr; - CsFuncPtr csScriptsFrameCleanUp = nullptr; - CsScriptManipFuncPtr csScriptsAdd = nullptr; - CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; - CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; - CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; - CsScriptSerialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; + CsFuncPtr csScriptsFrameSetUp = nullptr; + CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; + CsFuncPtr csScriptsExecuteUpdate = nullptr; + CsFuncPtr csScriptsExecuteLateUpdate = nullptr; + CsFuncPtr csScriptsFrameCleanUp = nullptr; + CsScriptManipFuncPtr csScriptsAdd = nullptr; + CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; + CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; + CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; + CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; // - Editor - CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; - CsFuncPtr csEditorUndo = nullptr; - CsFuncPtr csEditorRedo = nullptr; + CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; + CsFuncPtr csEditorUndo = nullptr; + CsFuncPtr csEditorRedo = nullptr; /*-----------------------------------------------------------------------------*/ /* Event Handler Functions */ diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index d0023107..63583cf2 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -79,6 +79,10 @@ namespace SHADE } } } + + // Deserialise scripts + if (node[ScriptsNode]) + SHSystemManager::GetSystem()->DeserialiseScripts(eid, node[ScriptsNode]); } void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path) @@ -186,9 +190,6 @@ namespace SHADE SHSystemManager::GetSystem()->SerialiseScripts(eid, scripts); node[ScriptsNode] = scripts; - //YAML::Emitter emitter; - //emitter << node; - //SHLOG_TRACE(emitter.c_str()) return node; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index b9423795..b6bc1815 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -481,14 +481,14 @@ namespace SHADE // Check if yamlNode is valid if (yamlNode == nullptr) { - Debug::LogWarning("Attempted to serialise scripts with an invalid YAML Node! Skipping."); + Debug::LogWarning("[ScriptStore] Attempted to serialise scripts with an invalid YAML Node! Skipping."); return false; } // Check if entity exists, otherwise nothing if (!EntityUtils::IsValid(entity)) { - Debug::LogWarning("Attempted to serialise scripts for an invalid Entity! Skipping."); + Debug::LogWarning("[ScriptStore] Attempted to serialise scripts for an invalid Entity! Skipping."); return false; } @@ -518,14 +518,14 @@ namespace SHADE // Check if yamlNode is valid if (yamlNode == nullptr) { - Debug::LogWarning("Attempted to deserialise scripts with an invalid YAML Node! Skipping."); + Debug::LogWarning("[ScriptStore] Attempted to deserialise scripts with an invalid YAML Node! Skipping."); return false; } // Check if entity exists, otherwise nothing if (!EntityUtils::IsValid(entity)) { - Debug::LogWarning("Attempted to deserialise scripts for an invalid Entity! Skipping."); + Debug::LogWarning("[ScriptStore] Attempted to deserialise scripts for an invalid Entity! Skipping."); return false; } @@ -533,17 +533,27 @@ namespace SHADE for (YAML::Node& node : *yamlNode) { // Get the name of the script - const std::string typeName = ""; // TODO + if (!node["Type"]) + { + Debug::LogWarning("[ScriptStore] Script with no type detected, skipping."); + continue; + } + + System::String^ typeName = Convert::ToCLI(node["Type"].as()); // Create Script^ script; - if (AddScriptViaNameWithRef(entity, Convert::ToCLI(typeName), script)) + if (AddScriptViaNameWithRef(entity, typeName, script)) { // Copy the data in ReflectionUtilities::Deserialise(script, node); - return true; + } + else + { + Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping."); } } + return true; SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") return false; diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ index a3d4c33b..7c39232a 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ @@ -27,7 +27,8 @@ namespace SHADE { if (fieldInfo->FieldType == FieldType::typeid) { - fieldNode = 0.0;//static_cast(safe_cast(fieldInfo->GetValue(object))); + const FieldType VALUE = safe_cast(fieldInfo->GetValue(object)); + fieldNode = static_cast(VALUE); return true; } @@ -37,7 +38,7 @@ namespace SHADE template bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { - return fieldAssignYaml(fieldInfo, object, node); + return fieldAssignYaml>(fieldInfo, object, node); } template diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx index fbae5ee0..403c913c 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx @@ -63,7 +63,6 @@ namespace SHADE /// The object to copy deserialised data into. static void Deserialise(System::Object^ object, YAML::Node& yamlNode); - private: /*-----------------------------------------------------------------------------*/ /* Serialization Helper Functions */ diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index b41ffef4..f04cbf4b 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -91,4 +91,68 @@ namespace SHADE /// Managed copy of a native std::string. static System::String^ ToCLI(const std::string& str); }; + + /// + /// Type Transformer for managed types to native types. + /// + /// + /// Managed type to get the native type for. + /// + template + struct ToNativeType + { + public: + using Value = void; + }; + template<> struct ToNativeType { using Value = int16_t; }; + template<> struct ToNativeType { using Value = int32_t; }; + template<> struct ToNativeType { using Value = int64_t; }; + template<> struct ToNativeType { using Value = uint16_t; }; + template<> struct ToNativeType { using Value = uint32_t; }; + template<> struct ToNativeType { using Value = uint64_t; }; + template<> struct ToNativeType { using Value = int8_t; }; + template<> struct ToNativeType { using Value = bool; }; + template<> struct ToNativeType { using Value = double; }; + template<> struct ToNativeType { using Value = float; }; + + /// + /// Alias for ToNativeType::Value + /// + /// + /// Managed type to get the native type for. + /// + template + using ToNativeType_T = typename ToNativeType::Value; + + /// + /// Type Transformer for native types to managed types. + /// + /// + /// Managed type to get the native type for. + /// + template + struct ToManagedType + { + public: + using Value = void; + }; + template<> struct ToManagedType { using Value = System::Byte; }; + template<> struct ToManagedType { using Value = System::Int16; }; + template<> struct ToManagedType { using Value = System::Int32; }; + template<> struct ToManagedType { using Value = System::Int64; }; + template<> struct ToManagedType { using Value = System::UInt16; }; + template<> struct ToManagedType { using Value = System::UInt32; }; + template<> struct ToManagedType { using Value = System::UInt64; }; + template<> struct ToManagedType { using Value = bool; }; + template<> struct ToManagedType { using Value = double; }; + template<> struct ToManagedType { using Value = float; }; + + /// + /// Alias for ToManagedType::Value + /// + /// + /// Managed type to get the native type for. + /// + template + using ToManagedType_T = typename ToManagedType::Value; }