From 3111c3cd37b75c7f6e36aee94dab42d0b7755d8f Mon Sep 17 00:00:00 2001 From: dave Date: Fri, 25 Jan 2019 15:41:31 -0700 Subject: [PATCH] POC done --- Source/UnrealEnginePython/Private/UEPyModule.cpp | 9 +++++++-- .../UnrealEnginePython/Public/PythonHouseKeeper.h | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index 704593c8d..228df74ba 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -1181,10 +1181,12 @@ static void ue_pyobject_dealloc(ue_PyUObject *self) #if defined(UEPY_MEMORY_DEBUG) UE_LOG(LogPython, Warning, TEXT("Destroying ue_PyUObject %p mapped to UObject %p"), self, self->ue_object); #endif + FUnrealEnginePythonHouseKeeper *housekeeper = FUnrealEnginePythonHouseKeeper::Get(); if (self->owned) { - FUnrealEnginePythonHouseKeeper::Get()->UntrackUObject(self->ue_object); + housekeeper->UntrackUObject(self->ue_object); } + housekeeper->UnregisterPyUObject(self->ue_object); if (self->auto_rooted && (self->ue_object && self->ue_object->IsValidLowLevel() && self->ue_object->IsRooted())) { @@ -1868,7 +1870,10 @@ ue_PyUObject *ue_get_python_uobject(UObject *ue_obj) ue_py_object->py_dict = PyDict_New(); ue_py_object->owned = 0; - FUnrealEnginePythonHouseKeeper::Get()->RegisterPyUObject(ue_obj, ue_py_object); + FUnrealEnginePythonHouseKeeper *housekeeper = FUnrealEnginePythonHouseKeeper::Get(); + housekeeper->RegisterPyUObject(ue_obj, ue_py_object); + Py_INCREF(ue_py_object); // this is needed only because the following decrefs it + housekeeper->TrackUObject(ue_obj); #if defined(UEPY_MEMORY_DEBUG) UE_LOG(LogPython, Warning, TEXT("CREATED UPyObject at %p for %p %s"), ue_py_object, ue_obj, *ue_obj->GetName()); diff --git a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h index ed36ecc63..52ec42e3b 100644 --- a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h +++ b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h @@ -167,6 +167,7 @@ class FUnrealEnginePythonHouseKeeper : public FGCObject { uint32 Garbaged = 0; TArray BrokenList; + TArray needDecRef; for (auto &UObjectPyItem : UObjectPyMapping) { UObject *Object = UObjectPyItem.Key; @@ -182,14 +183,26 @@ class FUnrealEnginePythonHouseKeeper : public FGCObject BrokenList.Add(Object); Garbaged++; } + else if (Tracker.PyUObject->ob_base.ob_refcnt == 1) + { // the tracker is the only thing keeping this alive, so release the last reference +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Warning, TEXT("Auto-decrefing UObject at %p %s"), Object, *Object->GetName()); +#endif + needDecRef.Add(Tracker.PyUObject); + } else { #if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Error, TEXT("UObject at %p %s is in use"), Object, *Object->GetName()); + UE_LOG(LogPython, Error, TEXT("UObject at %p %s is in use, py ref count %d"), Object, *Object->GetName(), Tracker.PyUObject->ob_base.ob_refcnt); #endif } } + for (ue_PyUObject *py_obj : needDecRef) + { + Py_DECREF(py_obj); // on the next GC run, this object will dealloc and unregister itself + } + for (UObject *Object : BrokenList) { FPythonUOjectTracker &Tracker = UObjectPyMapping[Object];