diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 89d43046d..009404cbc 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -36,6 +36,7 @@ #include "Editor/Editor.h" #include "Engine/Platform/MessageBox.h" #include "Engine/Engine/CommandLine.h" +#include "Engine/Serialization/JsonSerializer.h" #endif bool LayersMask::HasLayer(const StringView& layerName) const @@ -74,11 +75,25 @@ public: } }; +#if USE_EDITOR + +struct ScriptsReloadObject +{ + StringAnsi TypeName; + ScriptingObject** Object; + Array Data; +}; + +#endif + namespace LevelImpl { Array _sceneActions; CriticalSection _sceneActionsLocker; DateTime _lastSceneLoadTime(0); +#if USE_EDITOR + Array ScriptsReloadObjects; +#endif void CallSceneEvent(SceneEventType eventType, Scene* scene, Guid sceneId); @@ -559,6 +574,24 @@ public: Level::ScriptsReload(); Scripting::Reload(); + // Restore objects + for (auto& e : ScriptsReloadObjects) + { + const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(e.TypeName); + *e.Object = ScriptingObject::NewObject(typeHandle); + if (!*e.Object) + { + LOG(Warning, "Failed to restore hot-reloaded object of type {0}.", String(e.TypeName)); + continue; + } + auto* serializable = ScriptingObject::ToInterface(*e.Object); + if (serializable && e.Data.HasItems()) + { + JsonSerializer::LoadFromBytes(serializable, e.Data, FLAXENGINE_VERSION_BUILD); + } + } + ScriptsReloadObjects.Clear(); + // Restore scenes (from memory) for (int32 i = 0; i < scenesCount; i++) { @@ -595,6 +628,20 @@ public: } }; +void Level::ScriptsReloadRegisterObject(ScriptingObject*& obj) +{ + if (!obj) + return; + auto& e = ScriptsReloadObjects.AddOne(); + e.Object = &obj; + e.TypeName = obj->GetType().Fullname; + if (auto* serializable = ScriptingObject::ToInterface(obj)) + e.Data = JsonSerializer::SaveToBytes(serializable); + ScriptingObject* o = obj; + obj = nullptr; + o->DeleteObjectNow(); +} + #endif class SpawnActorAction : public SceneAction diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h index afd1553d1..241941872 100644 --- a/Source/Engine/Level/Level.h +++ b/Source/Engine/Level/Level.h @@ -215,6 +215,8 @@ public: /// API_EVENT() static Delegate SceneUnloaded; +#if USE_EDITOR + /// /// Fired when scene starts reloading scripts. /// @@ -230,6 +232,14 @@ public: /// API_EVENT() static Action ScriptsReloadEnd; + /// + /// Adds object to preserve during scripts reload. Called during ScriptsReloadStart event to serialize and destroy the object that should be restored when scripts reload ends. + /// + /// Reference to the object to preserve during the scripting reload. + static void ScriptsReloadRegisterObject(ScriptingObject*& obj); + +#endif + public: ///