Skip to content

Commit 90cbe9b

Browse files
author
Roberto De Ioris
committed
completed first part of UObject GC, Timer and Ticker refactoring
1 parent ff24810 commit 90cbe9b

File tree

11 files changed

+46
-70
lines changed

11 files changed

+46
-70
lines changed

Source/UnrealEnginePython/Private/PyActor.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,19 +289,12 @@ APyActor::~APyActor()
289289
{
290290
FScopePythonGIL gil;
291291

292-
#if defined(UEPY_MEMORY_DEBUG)
293-
if (py_actor_instance && py_actor_instance->ob_refcnt != 1)
294-
{
295-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python AActor wrapper refcnt = %d"), py_actor_instance->ob_refcnt);
296-
}
297-
#endif
298292
Py_XDECREF(py_actor_instance);
299293

300294
#if defined(UEPY_MEMORY_DEBUG)
301295
UE_LOG(LogPython, Warning, TEXT("Python AActor %p (mapped to %p) wrapper XDECREF'ed"), this, py_uobject ? py_uobject->py_proxy : nullptr);
302296
#endif
303297

304-
305298
Py_XDECREF(py_uobject);
306299
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
307300

Source/UnrealEnginePython/Private/PyCharacter.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,7 @@ APyCharacter::~APyCharacter()
443443
{
444444
FScopePythonGIL gil;
445445

446-
#if defined(UEPY_MEMORY_DEBUG)
447-
if (py_character_instance && py_character_instance->ob_refcnt != 1) {
448-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python ACharacter wrapper refcnt = %d"), py_character_instance->ob_refcnt);
449-
}
450-
#endif
446+
451447
Py_XDECREF(py_character_instance);
452448

453449
#if defined(UEPY_MEMORY_DEBUG)
@@ -456,4 +452,5 @@ APyCharacter::~APyCharacter()
456452

457453
// this could trigger the distruction of the python/uobject mapper
458454
Py_XDECREF(py_uobject);
455+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
459456
}

Source/UnrealEnginePython/Private/PyHUD.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,7 @@ APyHUD::~APyHUD()
242242
{
243243
FScopePythonGIL gil;
244244

245-
#if defined(UEPY_MEMORY_DEBUG)
246-
if (py_hud_instance && py_hud_instance->ob_refcnt != 1)
247-
{
248-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python AHUD wrapper refcnt = %d"), py_hud_instance->ob_refcnt);
249-
}
250-
#endif
245+
251246
Py_XDECREF(py_hud_instance);
252247

253248
#if defined(UEPY_MEMORY_DEBUG)
@@ -256,4 +251,5 @@ APyHUD::~APyHUD()
256251

257252
// this could trigger the distruction of the python/uobject mapper
258253
Py_XDECREF(py_uobject);
254+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
259255
}

Source/UnrealEnginePython/Private/PyPawn.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,12 @@ APyPawn::~APyPawn()
239239
{
240240
FScopePythonGIL gil;
241241

242-
#if defined(UEPY_MEMORY_DEBUG)
243-
if (py_pawn_instance && py_pawn_instance->ob_refcnt != 1) {
244-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python APawn wrapper refcnt = %d"), py_pawn_instance->ob_refcnt);
245-
}
246-
#endif
247-
Py_XDECREF(py_pawn_instance);
248-
249-
242+
#
250243
#if defined(UEPY_MEMORY_DEBUG)
251244
UE_LOG(LogPython, Warning, TEXT("Python APawn (mapped to %p) wrapper XDECREF'ed"), py_uobject ? py_uobject->py_proxy : nullptr);
252245
#endif
253246

254247
// this could trigger the distruction of the python/uobject mapper
255248
Py_XDECREF(py_uobject);
249+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
256250
}

Source/UnrealEnginePython/Private/PyUserWidget.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,6 @@ UPyUserWidget::~UPyUserWidget()
355355
{
356356
FScopePythonGIL gil;
357357

358-
#if defined(UEPY_MEMORY_DEBUG)
359-
if (py_user_widget_instance && py_user_widget_instance->ob_refcnt != 1) {
360-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python UUserWidget wrapper refcnt = %d"), py_user_widget_instance->ob_refcnt);
361-
}
362-
#endif
363358
Py_XDECREF(py_user_widget_instance);
364359

365360
#if defined(UEPY_MEMORY_DEBUG)
@@ -368,6 +363,7 @@ UPyUserWidget::~UPyUserWidget()
368363

369364
// this could trigger the distruction of the python/uobject mapper
370365
Py_XDECREF(py_uobject);
366+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
371367
}
372368

373369
void UPyUserWidget::CallPythonUserWidgetMethod(FString method_name, FString args)

Source/UnrealEnginePython/Private/PythonComponent.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -556,11 +556,7 @@ UPythonComponent::~UPythonComponent()
556556
{
557557
FScopePythonGIL gil;
558558

559-
#if defined(UEPY_MEMORY_DEBUG)
560-
if (py_component_instance && py_component_instance->ob_refcnt != 1) {
561-
UE_LOG(LogPython, Error, TEXT("Inconsistent Python UActorComponent wrapper refcnt = %d"), py_component_instance->ob_refcnt);
562-
}
563-
#endif
559+
#
564560
Py_XDECREF(py_component_instance);
565561

566562
#if defined(UEPY_MEMORY_DEBUG)
@@ -569,4 +565,5 @@ UPythonComponent::~UPythonComponent()
569565

570566
// this could trigger the distruction of the python/uobject mapper
571567
Py_XDECREF(py_uobject);
568+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
572569
}

Source/UnrealEnginePython/Private/PythonDelegate.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ void UPythonDelegate::SetPyCallable(PyObject *callable)
1212
// do not acquire the gil here as we set the callable in python call themselves
1313
py_callable = callable;
1414
Py_INCREF(py_callable);
15-
UE_LOG(LogPython, Error, TEXT("CALLABLE %d"), py_callable->ob_refcnt);
1615
}
1716

1817
void UPythonDelegate::SetSignature(UFunction *original_signature)
@@ -106,12 +105,8 @@ UPythonDelegate::~UPythonDelegate()
106105
{
107106
FScopePythonGIL gil;
108107

109-
if (py_callable)
110-
{
111-
UE_LOG(LogPython, Error, TEXT("DELEGATE N %d\n"), py_callable->ob_refcnt);
112-
}
113108
Py_XDECREF(py_callable);
114109
#if defined(UEPY_MEMORY_DEBUG)
115-
UE_LOG(LogPython, Warning, TEXT("PythonDelegate callable XDECREF'ed"));
110+
UE_LOG(LogPython, Warning, TEXT("PythonDelegate %p callable XDECREF'ed"), this);
116111
#endif
117112
}

Source/UnrealEnginePython/Private/PythonFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ void UPythonFunction::CallPythonCallable(FFrame& Stack, RESULT_DECL)
122122
UPythonFunction::~UPythonFunction()
123123
{
124124
Py_XDECREF(py_callable);
125+
FUnrealEnginePythonHouseKeeper::Get()->UnregisterPyUObject(this);
125126
#if defined(UEPY_MEMORY_DEBUG)
126-
UE_LOG(LogPython, Warning, TEXT("PythonFunction callable XDECREF'ed"));
127+
UE_LOG(LogPython, Warning, TEXT("PythonFunction callable %p XDECREF'ed"), this);
127128
#endif
128129
}

Source/UnrealEnginePython/Private/UEPyTicker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ typedef struct {
99
/* Type-specific fields go here. */
1010
FDelegateHandle dhandle;
1111
bool garbaged;
12-
TSharedPtr<FTickerDelegate> delegate_ptr;
12+
TSharedPtr<FPythonSmartDelegate> delegate_ptr;
1313
} ue_PyFDelegateHandle;
1414

1515
PyObject *py_unreal_engine_add_ticker(PyObject *, PyObject *);

Source/UnrealEnginePython/Private/UEPyTimer.cpp

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,26 @@
44

55
static PyObject *py_ue_ftimerhandle_clear(ue_PyFTimerHandle *self, PyObject * args)
66
{
7-
self->world->GetTimerManager().ClearTimer(self->thandle);
8-
Py_INCREF(Py_None);
9-
return Py_None;
7+
if (!self->world.IsValid())
8+
return PyErr_Format(PyExc_Exception, "World's timer is invalid");
9+
self->world.Get()->GetTimerManager().ClearTimer(self->thandle);
10+
Py_RETURN_NONE;
1011
}
1112

1213
static PyObject *py_ue_ftimerhandle_pause(ue_PyFTimerHandle *self, PyObject * args)
1314
{
14-
self->world->GetTimerManager().PauseTimer(self->thandle);
15-
Py_INCREF(Py_None);
16-
return Py_None;
15+
if (!self->world.IsValid())
16+
return PyErr_Format(PyExc_Exception, "World's timer is invalid");
17+
self->world.Get()->GetTimerManager().PauseTimer(self->thandle);
18+
Py_RETURN_NONE;
1719
}
1820

1921
static PyObject *py_ue_ftimerhandle_unpause(ue_PyFTimerHandle *self, PyObject * args)
2022
{
21-
self->world->GetTimerManager().UnPauseTimer(self->thandle);
22-
Py_INCREF(Py_None);
23-
return Py_None;
23+
if (!self->world.IsValid())
24+
return PyErr_Format(PyExc_Exception, "World's timer is invalid");
25+
self->world.Get()->GetTimerManager().UnPauseTimer(self->thandle);
26+
Py_RETURN_NONE;
2427
}
2528

2629

@@ -37,7 +40,14 @@ static PyMethodDef ue_PyFTimerHandle_methods[] = {
3740
// destructor
3841
static void ue_pyftimerhandle_dealloc(ue_PyFTimerHandle *self)
3942
{
40-
Py_DECREF(self->py_callable);
43+
if (self->world.IsValid())
44+
{
45+
self->world.Get()->GetTimerManager().ClearTimer(self->thandle);
46+
}
47+
if (self->delegate_ptr.IsValid())
48+
{
49+
self->delegate_ptr.Reset();
50+
}
4151
Py_TYPE(self)->tp_free((PyObject *)self);
4252
}
4353

@@ -107,26 +117,24 @@ PyObject *py_ue_set_timer(ue_PyUObject *self, PyObject * args)
107117
if (!world)
108118
return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject");
109119

110-
FTimerDelegate timer_delegate;
111-
TSharedRef<FPythonSmartDelegate> py_delegate = MakeShareable(new FPythonSmartDelegate);
112-
py_delegate->SetPyCallable(py_callable);
113-
114-
timer_delegate.BindSP(py_delegate, &FPythonSmartDelegate::Void);
115120

116-
FTimerHandle thandle;
117-
world->GetTimerManager().SetTimer(thandle, timer_delegate, rate, loop, first_delay);
118121

119122
ue_PyFTimerHandle *ret = (ue_PyFTimerHandle *)PyObject_New(ue_PyFTimerHandle, &ue_PyFTimerHandleType);
120123
if (!ret)
121124
{
122-
world->GetTimerManager().ClearTimer(thandle);
123125
return PyErr_Format(PyExc_Exception, "unable to allocate FTimerHandle python object");
124126
}
125-
ret->thandle = thandle;
126-
ret->py_callable = py_callable;
127-
// will be decref'ed on clear
128-
Py_INCREF(ret->py_callable);
129-
ret->world = world;
127+
128+
FTimerDelegate timer_delegate;
129+
TSharedRef<FPythonSmartDelegate> py_delegate = MakeShareable(new FPythonSmartDelegate);
130+
py_delegate->SetPyCallable(py_callable);
131+
132+
timer_delegate.BindSP(py_delegate, &FPythonSmartDelegate::Void);
133+
134+
world->GetTimerManager().SetTimer(ret->thandle, timer_delegate, rate, loop, first_delay);
135+
136+
new(&ret->delegate_ptr) TSharedPtr<FPythonSmartDelegate>(py_delegate);
137+
ret->world = TWeakObjectPtr<UWorld>(world);
130138

131139
return (PyObject *)ret;
132140
}

0 commit comments

Comments
 (0)