Add logging and cleaning up leaked scene objects after play mode in Editor
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
#include "Engine/Renderer/ProbesRenderer.h"
|
||||
#include "Engine/Animations/Graph/AnimGraph.h"
|
||||
#include "Engine/Core/ObjectsRemovalService.h"
|
||||
|
||||
ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions;
|
||||
|
||||
@@ -572,6 +573,29 @@ bool ManagedEditor::EvaluateVisualScriptLocal(VisualScript* script, VisualScript
|
||||
return false;
|
||||
}
|
||||
|
||||
void ManagedEditor::WipeOutLeftoverSceneObjects()
|
||||
{
|
||||
Array<ScriptingObject*> objects = Scripting::GetObjects();
|
||||
bool removedAny = false;
|
||||
for (ScriptingObject* object : objects)
|
||||
{
|
||||
if (EnumHasAllFlags(object->Flags, ObjectFlags::IsDuringPlay) && EnumHasNoneFlags(object->Flags, ObjectFlags::WasMarkedToDelete))
|
||||
{
|
||||
if (auto* sceneObject = Cast<SceneObject>(object))
|
||||
{
|
||||
if (sceneObject->HasParent())
|
||||
continue; // Skip sub-objects
|
||||
|
||||
LOG(Error, "Object '{}' (ID={}, Type={}) is still in memory after play end but should be destroyed (memory leak).", sceneObject->GetNamePath(), sceneObject->GetID(), sceneObject->GetType().ToString());
|
||||
sceneObject->DeleteObject();
|
||||
removedAny = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removedAny)
|
||||
ObjectsRemovalService::Flush();
|
||||
}
|
||||
|
||||
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
||||
{
|
||||
ASSERT(!HasManagedInstance());
|
||||
|
||||
@@ -241,6 +241,7 @@ public:
|
||||
API_FUNCTION(Internal) static VisualScriptStackFrame GetVisualScriptPreviousScopeFrame();
|
||||
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
||||
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
||||
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
|
||||
|
||||
private:
|
||||
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace FlaxEditor.States
|
||||
|
||||
// Restore editor scene
|
||||
SceneRestoring?.Invoke();
|
||||
_duplicateScenes.DeletedScenes();
|
||||
_duplicateScenes.UnloadScenes();
|
||||
PluginManager.Internal_DeinitializeGamePlugins();
|
||||
Editor.Internal_SetPlayMode(false);
|
||||
_duplicateScenes.RestoreSceneData();
|
||||
|
||||
@@ -120,9 +120,9 @@ namespace FlaxEditor.Utilities
|
||||
/// <summary>
|
||||
/// Deletes the creates scenes for the simulation.
|
||||
/// </summary>
|
||||
public void DeletedScenes()
|
||||
public void UnloadScenes()
|
||||
{
|
||||
Profiler.BeginEvent("DuplicateScenes.DeletedScenes");
|
||||
Profiler.BeginEvent("DuplicateScenes.UnloadScenes");
|
||||
Editor.Log("Restoring scene data");
|
||||
|
||||
// TODO: here we can keep changes for actors marked to keep their state after simulation
|
||||
@@ -134,6 +134,8 @@ namespace FlaxEditor.Utilities
|
||||
throw new Exception("Failed to unload scenes.");
|
||||
}
|
||||
FlaxEngine.Scripting.FlushRemovedObjects();
|
||||
Editor.WipeOutLeftoverSceneObjects();
|
||||
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -721,6 +721,15 @@ void Scripting::Reload(bool canTriggerSceneReload)
|
||||
|
||||
#endif
|
||||
|
||||
Array<ScriptingObject*, HeapAllocation> Scripting::GetObjects()
|
||||
{
|
||||
Array<ScriptingObject*> objects;
|
||||
_objectsLocker.Lock();
|
||||
_objectsDictionary.GetValues(objects);
|
||||
_objectsLocker.Unlock();
|
||||
return objects;
|
||||
}
|
||||
|
||||
MClass* Scripting::FindClass(const StringAnsiView& fullname)
|
||||
{
|
||||
if (fullname.IsEmpty())
|
||||
|
||||
@@ -79,6 +79,13 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered scripting objects.
|
||||
/// </summary>
|
||||
/// <remarks>Use with caution due to potentially large memory allocation.</remarks>
|
||||
/// <returns>The collection of the objects.</returns>
|
||||
static Array<ScriptingObject*, HeapAllocation> GetObjects();
|
||||
|
||||
/// <summary>
|
||||
/// Finds the class with given fully qualified name within whole assembly.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user