Fixed bugs related to C# script serialization and deserialization #277

Merged
Pycorax merged 4 commits from SP3-6-c-scripting into main 2022-11-25 00:08:58 +08:00
7 changed files with 64 additions and 5 deletions

View File

@ -197,12 +197,18 @@ namespace SHADE
if (BUILD_SUCCESS) if (BUILD_SUCCESS)
{ {
// Copy to built dll to the working directory and replace // Copy to built dll to the working directory and replace
std::filesystem::copy_file("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing); if (!copyFile("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing))
{
SHLOG_ERROR("[ScriptEngine] Failed to replace scripts assembly. Scripts will remain outdated.");
}
// If debug, we want to copy the PDB so that we can do script debugging // If debug, we want to copy the PDB so that we can do script debugging
if (debug) if (debug)
{ {
std::filesystem::copy_file("./tmp/SHADE_Scripting.pdb", "SHADE_Scripting.pdb", std::filesystem::copy_options::overwrite_existing); if (!copyFile("./tmp/SHADE_Scripting.pdb", "SHADE_Scripting.pdb", std::filesystem::copy_options::overwrite_existing))
{
SHLOG_WARNING("[ScriptEngine] Breakpoint debugging will not work as PDB cannot be updated. If you are currently debugging, stop the debugger first.");
}
} }
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!"; oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
@ -591,6 +597,19 @@ namespace SHADE
return false; return false;
} }
bool SHScriptEngine::copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept
{
try
{
return std::filesystem::copy_file(from, to, options);
}
catch (std::exception& e)
{
SHLOG_ERROR("[ScriptEngine] Failed to copy file {} ({})", to.string(), std::string(e.what()));
return false;
}
}
DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args) DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args)
{ {
STARTUPINFOW startInfo; STARTUPINFOW startInfo;

View File

@ -319,6 +319,7 @@ namespace SHADE
/// <param name="filePath">File path to the file to check.</param> /// <param name="filePath">File path to the file to check.</param>
/// <returns> True if the file exists </returns> /// <returns> True if the file exists </returns>
static bool fileExists(const std::filesystem::path& filePath); static bool fileExists(const std::filesystem::path& filePath);
static bool copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept;
static DWORD execProcess(const std::wstring& path, const std::wstring& args); static DWORD execProcess(const std::wstring& path, const std::wstring& args);
static std::wstring generateBuildCommand(bool debug); static std::wstring generateBuildCommand(bool debug);
}; };

View File

@ -200,7 +200,16 @@ namespace SHADE
{ {
if (SHEditorUI::Button("Add Item")) if (SHEditorUI::Button("Add Item"))
{ {
System::Object^ obj = System::Activator::CreateInstance(listType); System::Object^ obj;
if (listType == System::String::typeid)
{
// Special case for string
obj = gcnew System::String("");
}
else
{
obj = System::Activator::CreateInstance(listType);
}
iList->Add(obj); iList->Add(obj);
registerUndoListAddAction(listType, iList, iList->Count - 1, obj); registerUndoListAddAction(listType, iList, iList->Count - 1, obj);
} }

View File

@ -74,7 +74,7 @@ namespace SHADE
// Add the script in // Add the script in
script->Initialize(GameObject(entity)); script->Initialize(GameObject(entity));
entityScriptList->Insert(System::Math::Clamp(index, 0, entityScriptList->Count), script); entityScriptList->Insert(System::Math::Clamp(index, 0, entityScriptList->Count), script);
if (Application::IsPlaying && !SHSceneManager::HasSceneChanged()) if (Application::IsPlaying && !isDeserialising)
{ {
// Only call immediately if we are in game and is not loading another scene // Only call immediately if we are in game and is not loading another scene
script->Awake(); script->Awake();
@ -423,6 +423,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void ScriptStore::Init() void ScriptStore::Init()
{ {
isDeserialising = false;
// Create an enumerable list of script types // Create an enumerable list of script types
refreshScriptTypeList(); refreshScriptTypeList();
// Get stored methods for interop variants of functions // Get stored methods for interop variants of functions
@ -724,6 +726,10 @@ namespace SHADE
bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr) bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Flag that deserialization processs is ongoing
isDeserialising = true;
// Convert to pointer // Convert to pointer
YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer()); YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer());
@ -765,9 +771,16 @@ namespace SHADE
Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping."); Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping.");
} }
} }
// Unset flag for deserialization process
isDeserialising = false;
return true; return true;
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
// Unset flag for deserialization process
isDeserialising = false;
return false; return false;
} }

View File

@ -337,6 +337,7 @@ namespace SHADE
static ScriptSet disposalQueue; static ScriptSet disposalQueue;
static System::Collections::Generic::IEnumerable<System::Type^>^ scriptTypeList; static System::Collections::Generic::IEnumerable<System::Type^>^ scriptTypeList;
static System::Reflection::MethodInfo^ addScriptMethod; static System::Reflection::MethodInfo^ addScriptMethod;
static bool isDeserialising;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -279,7 +279,15 @@ namespace SHADE
for (int i = 0; i < LIST_SIZE; ++i) for (int i = 0; i < LIST_SIZE; ++i)
{ {
// Create the object // Create the object
System::Object^ obj = System::Activator::CreateInstance(elemType); System::Object^ obj;
if (elemType == System::String::typeid)
{
obj = gcnew System::String("");
}
else
{
obj = System::Activator::CreateInstance(elemType);
}
// Set it's value // Set it's value
if (varAssignYaml(obj, node[i])) if (varAssignYaml(obj, node[i]))

View File

@ -167,6 +167,10 @@ namespace SHADE
{ {
valueObj = 0; valueObj = 0;
} }
else
{
return false;
}
} }
else else
{ {
@ -181,6 +185,10 @@ namespace SHADE
valueObj = FieldType(); valueObj = FieldType();
} }
} }
else
{
return false;
}
} }
} }