diff --git a/Source/UnrealEnginePython/Private/FMModule.cpp b/Source/UnrealEnginePython/Private/FMModule.cpp index 423e11edc..68f605fb5 100644 --- a/Source/UnrealEnginePython/Private/FMModule.cpp +++ b/Source/UnrealEnginePython/Private/FMModule.cpp @@ -227,7 +227,7 @@ static PyObject *create_subclass(PyObject *self, PyObject *args) if (!pyInst) { LERROR("failed to instantiate python class"); - PyErr_Format(PyExc_Exception, "Failed to instantiate python clsas"); + PyErr_Format(PyExc_Exception, "Failed to instantiate python class"); return; } pyObj->py_proxy = pyInst; // pyInst's ref is now owned by py_proxy. TODO: who decref's this later? diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index 63190bcc9..cec31558b 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -1181,12 +1181,10 @@ 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) { - housekeeper->UntrackUObject(self->ue_object); + FUnrealEnginePythonHouseKeeper::Get()->UntrackUObject(self->ue_object); } - housekeeper->UnregisterPyUObject(self->ue_object); if (self->auto_rooted && (self->ue_object && self->ue_object->IsValidLowLevel() && self->ue_object->IsRooted())) { @@ -1329,7 +1327,9 @@ static int ue_PyUObject_setattro(ue_PyUObject *self, PyObject *attr_name, PyObje { #if WITH_EDITOR if (!self->creating) - self->ue_object->PreEditChange(u_property); + { + self->ue_object->PreEditChange(u_property); + } #endif if (ue_py_convert_pyobject(value, u_property, (uint8*)self->ue_object, 0)) { @@ -1874,10 +1874,7 @@ ue_PyUObject *ue_get_python_uobject(UObject *ue_obj) ue_py_object->py_dict = PyDict_New(); ue_py_object->owned = 0; - 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); + FUnrealEnginePythonHouseKeeper::Get()->RegisterPyUObject(ue_obj, ue_py_object); #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/FMPythonClass.cpp b/Source/UnrealEnginePython/Public/FMPythonClass.cpp index 9edb23859..c85226600 100644 --- a/Source/UnrealEnginePython/Public/FMPythonClass.cpp +++ b/Source/UnrealEnginePython/Public/FMPythonClass.cpp @@ -20,3 +20,15 @@ void UFMPythonClass::CallPyConstructor(ue_PyUObject *self) } +UObject* UFMPythonClass::CreateDefaultObject() +{ + bool savedLoad = GIsInitialLoad; + + // this is a total hack but be need to go around the default + // package loading logic when loading default objects + GIsInitialLoad = false; + UObject *ret = Super::CreateDefaultObject(); + GIsInitialLoad = savedLoad; + + return ret; +} diff --git a/Source/UnrealEnginePython/Public/FMPythonClass.h b/Source/UnrealEnginePython/Public/FMPythonClass.h index 4ada7a350..6ef585cf7 100644 --- a/Source/UnrealEnginePython/Public/FMPythonClass.h +++ b/Source/UnrealEnginePython/Public/FMPythonClass.h @@ -22,6 +22,9 @@ class UFMPythonClass : public UClass // true while we're creating this class (including the stuff in Python) bool creating; +protected: + virtual UObject* CreateDefaultObject() override; + private: PyObject * py_constructor; diff --git a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h index 52ec42e3b..ed36ecc63 100644 --- a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h +++ b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h @@ -167,7 +167,6 @@ class FUnrealEnginePythonHouseKeeper : public FGCObject { uint32 Garbaged = 0; TArray BrokenList; - TArray needDecRef; for (auto &UObjectPyItem : UObjectPyMapping) { UObject *Object = UObjectPyItem.Key; @@ -183,26 +182,14 @@ 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, py ref count %d"), Object, *Object->GetName(), Tracker.PyUObject->ob_base.ob_refcnt); + UE_LOG(LogPython, Error, TEXT("UObject at %p %s is in use"), Object, *Object->GetName()); #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];