Skip to content

Commit a1b8c99

Browse files
author
Roberto De Ioris
committed
first round of shared pointers refactoring
1 parent 0829853 commit a1b8c99

File tree

12 files changed

+137
-90
lines changed

12 files changed

+137
-90
lines changed

Source/UnrealEnginePython/Private/ConsoleManager/UEPyIConsoleManager.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ static PyObject *py_ue_iconsole_manager_register_variable_float(PyObject *cls, P
515515
Py_RETURN_NONE;
516516
}
517517

518-
void UPythonConsoleDelegate::OnConsoleCommand(const TArray < FString > & InArgs)
518+
void FPythonSmartConsoleDelegate::OnConsoleCommand(const TArray < FString > & InArgs)
519519
{
520520
FScopePythonGIL gil;
521521

@@ -563,11 +563,10 @@ static PyObject *py_ue_iconsole_manager_register_command(PyObject *cls, PyObject
563563
return PyErr_Format(PyExc_Exception, "console object \"%s\" already exists", key);
564564
}
565565

566-
UPythonConsoleDelegate *py_delegate = NewObject<UPythonConsoleDelegate>();
566+
TSharedRef<FPythonSmartConsoleDelegate> py_delegate = MakeShareable(new FPythonSmartConsoleDelegate);
567567
py_delegate->SetPyCallable(py_callable);
568-
py_delegate->AddToRoot();
569568
FConsoleCommandWithArgsDelegate console_delegate;
570-
console_delegate.BindUObject(py_delegate, &UPythonConsoleDelegate::OnConsoleCommand);
569+
console_delegate.BindSP(py_delegate, &FPythonSmartConsoleDelegate::OnConsoleCommand);
571570

572571
if (!IConsoleManager::Get().RegisterConsoleCommand(UTF8_TO_TCHAR(key), help ? UTF8_TO_TCHAR(help) : UTF8_TO_TCHAR(key), console_delegate, 0))
573572
{

Source/UnrealEnginePython/Private/ConsoleManager/UEPyIConsoleManager.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@
33
#include "UnrealEnginePython.h"
44

55
#include "Runtime/Core/Public/HAL/IConsoleManager.h"
6-
#include "UEPyIConsoleManager.generated.h"
76

87
typedef struct
98
{
109
PyObject_HEAD
11-
/* Type-specific fields go here. */
10+
/* Type-specific fields go here. */
1211
} ue_PyIConsoleManager;
1312

14-
UCLASS()
15-
class UPythonConsoleDelegate : public UPythonDelegate
13+
class FPythonSmartConsoleDelegate : public FPythonSmartDelegate
1614
{
17-
GENERATED_BODY()
1815

1916
public:
2017
void OnConsoleCommand(const TArray < FString > &InArgs);

Source/UnrealEnginePython/Private/PythonDelegate.cpp

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include "UnrealEnginePythonPrivatePCH.h"
22
#include "PythonDelegate.h"
33

4-
UPythonDelegate::UPythonDelegate() {
4+
UPythonDelegate::UPythonDelegate()
5+
{
56
py_callable = nullptr;
67
signature_set = false;
78
}
@@ -29,15 +30,18 @@ void UPythonDelegate::ProcessEvent(UFunction *function, void *Parms)
2930

3031
PyObject *py_args = nullptr;
3132

32-
if (signature_set) {
33+
if (signature_set)
34+
{
3335
py_args = PyTuple_New(signature->NumParms);
3436
Py_ssize_t argn = 0;
3537

3638
TFieldIterator<UProperty> PArgs(signature);
37-
for (; PArgs && argn < signature->NumParms && ((PArgs->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm); ++PArgs) {
39+
for (; PArgs && argn < signature->NumParms && ((PArgs->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm); ++PArgs)
40+
{
3841
UProperty *prop = *PArgs;
3942
PyObject *arg = ue_py_convert_property(prop, (uint8 *)Parms);
40-
if (!arg) {
43+
if (!arg)
44+
{
4145
unreal_engine_py_log_error();
4246
Py_DECREF(py_args);
4347
return;
@@ -49,7 +53,8 @@ void UPythonDelegate::ProcessEvent(UFunction *function, void *Parms)
4953

5054
PyObject *ret = PyObject_CallObject(py_callable, py_args);
5155
Py_XDECREF(py_args);
52-
if (!ret) {
56+
if (!ret)
57+
{
5358
unreal_engine_py_log_error();
5459
return;
5560
}
@@ -75,7 +80,8 @@ void UPythonDelegate::PyInputHandler()
7580
{
7681
FScopePythonGIL gil;
7782
PyObject *ret = PyObject_CallObject(py_callable, NULL);
78-
if (!ret) {
83+
if (!ret)
84+
{
7985
unreal_engine_py_log_error();
8086
return;
8187
}
@@ -86,41 +92,13 @@ void UPythonDelegate::PyInputAxisHandler(float value)
8692
{
8793
FScopePythonGIL gil;
8894
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"f", value);
89-
if (!ret) {
90-
unreal_engine_py_log_error();
91-
return;
92-
}
93-
Py_DECREF(ret);
94-
}
95-
96-
bool UPythonDelegate::Tick(float DeltaTime)
97-
{
98-
FScopePythonGIL gil;
99-
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"f", DeltaTime);
100-
if (!ret) {
101-
unreal_engine_py_log_error();
102-
return false;
103-
}
104-
if (PyObject_IsTrue(ret)) {
105-
Py_DECREF(ret);
106-
return true;
107-
}
108-
Py_DECREF(ret);
109-
return false;
110-
}
111-
112-
#if WITH_EDITOR
113-
void UPythonDelegate::PyFOnAssetPostImport(UFactory *factory, UObject *u_object)
114-
{
115-
FScopePythonGIL gil;
116-
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"OO", ue_get_python_uobject((UObject *)factory), ue_get_python_uobject(u_object));
117-
if (!ret) {
95+
if (!ret)
96+
{
11897
unreal_engine_py_log_error();
11998
return;
12099
}
121100
Py_DECREF(ret);
122101
}
123-
#endif
124102

125103

126104
UPythonDelegate::~UPythonDelegate()
@@ -130,4 +108,4 @@ UPythonDelegate::~UPythonDelegate()
130108
#if defined(UEPY_MEMORY_DEBUG)
131109
UE_LOG(LogPython, Warning, TEXT("PythonDelegate callable XDECREF'ed"));
132110
#endif
133-
}
111+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "UnrealEnginePythonPrivatePCH.h"
2+
#include "PythonSmartDelegate.h"
3+
4+
FPythonSmartDelegate::FPythonSmartDelegate()
5+
{
6+
py_callable = nullptr;
7+
}
8+
9+
void FPythonSmartDelegate::SetPyCallable(PyObject *callable)
10+
{
11+
// do not acquire the gil here as we set the callable in python call themselves
12+
py_callable = callable;
13+
Py_INCREF(py_callable);
14+
}
15+
16+
17+
18+
bool FPythonSmartDelegate::Tick(float DeltaTime)
19+
{
20+
FScopePythonGIL gil;
21+
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"f", DeltaTime);
22+
if (!ret)
23+
{
24+
unreal_engine_py_log_error();
25+
return false;
26+
}
27+
if (PyObject_IsTrue(ret))
28+
{
29+
Py_DECREF(ret);
30+
return true;
31+
}
32+
Py_DECREF(ret);
33+
return false;
34+
}
35+
36+
#if WITH_EDITOR
37+
void FPythonSmartDelegate::PyFOnAssetPostImport(UFactory *factory, UObject *u_object)
38+
{
39+
FScopePythonGIL gil;
40+
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"OO", ue_get_python_uobject((UObject *)factory), ue_get_python_uobject(u_object));
41+
if (!ret)
42+
{
43+
unreal_engine_py_log_error();
44+
return;
45+
}
46+
Py_DECREF(ret);
47+
48+
}
49+
#endif
50+
51+
52+
FPythonSmartDelegate::~FPythonSmartDelegate()
53+
{
54+
FScopePythonGIL gil;
55+
Py_XDECREF(py_callable);
56+
#if defined(UEPY_MEMORY_DEBUG)
57+
UE_LOG(LogPython, Warning, TEXT("PythonSmartDelegate callable XDECREF'ed"));
58+
#endif
59+
}

Source/UnrealEnginePython/Private/UEPyEditor.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ PyObject *py_unreal_engine_blueprint_set_variable_visibility(PyObject * self, Py
14041404
if (!PyArg_ParseTuple(args, "OsO:blueprint_set_variable_visibility", &py_blueprint, &name, &visibility))
14051405
{
14061406
return NULL;
1407-
}
1407+
}
14081408

14091409
if (!ue_is_pyuobject(py_blueprint))
14101410
{
@@ -1678,12 +1678,10 @@ PyObject *py_unreal_engine_editor_on_asset_post_import(PyObject * self, PyObject
16781678
if (!PyCallable_Check(py_callable))
16791679
return PyErr_Format(PyExc_Exception, "object is not a callable");
16801680

1681-
UPythonDelegate *py_delegate = NewObject<UPythonDelegate>();
1681+
TSharedRef<FPythonSmartDelegate> py_delegate = MakeShareable(new FPythonSmartDelegate);
16821682
py_delegate->SetPyCallable(py_callable);
1683-
py_delegate->AddToRoot();
1684-
FEditorDelegates::OnAssetPostImport.AddUObject(py_delegate, &UPythonDelegate::PyFOnAssetPostImport);
1685-
Py_INCREF(Py_None);
1686-
return Py_None;
1683+
FEditorDelegates::OnAssetPostImport.AddSP(py_delegate, &FPythonSmartDelegate::PyFOnAssetPostImport);
1684+
Py_RETURN_NONE;
16871685
}
16881686

16891687
PyObject *py_unreal_engine_create_material_instance(PyObject * self, PyObject * args)

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,7 +2156,7 @@ void unreal_engine_py_log_error()
21562156
if (zero)
21572157
{
21582158
msg = PyBytes_AsString(zero);
2159-
}
2159+
}
21602160
#else
21612161
msg = PyString_AsString(PyObject_Str(value));
21622162
#endif
@@ -2211,7 +2211,7 @@ void unreal_engine_py_log_error()
22112211
}
22122212

22132213
PyErr_Clear();
2214-
}
2214+
}
22152215

22162216
// retrieve a UWorld from a generic UObject (if possible)
22172217
UWorld *ue_get_uworld(ue_PyUObject *py_obj)
@@ -3102,10 +3102,10 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *
31023102
#else
31033103
prop->ImportText(*default_key_value, prop->ContainerPtrToValuePtr<uint8>(buffer), PPF_Localized, NULL);
31043104
#endif
3105-
}
3105+
}
31063106
#endif
3107+
}
31073108
}
3108-
}
31093109

31103110

31113111
Py_ssize_t tuple_len = PyTuple_Size(args);

Source/UnrealEnginePython/Private/UEPyModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "UnrealEnginePython.h"
44
#include "PythonDelegate.h"
5+
#include "PythonSmartDelegate.h"
56
#include "UEPyUScriptStruct.h"
67
#include <map>
78
#include <list>

Source/UnrealEnginePython/Private/UEPyTicker.cpp

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
#include "UEPyTicker.h"
44

55
// destructor
6-
static void ue_pyfdelegatehandle_dealloc(ue_PyFDelegateHandle *self) {
7-
if (!self->garbaged) {
6+
static void ue_pyfdelegatehandle_dealloc(ue_PyFDelegateHandle *self)
7+
{
8+
if (!self->garbaged)
9+
{
810
FTicker::GetCoreTicker().RemoveTicker(self->dhandle);
911
// useless ;)
1012
self->garbaged = true;
1113
}
12-
if (self->py_delegate && self->py_delegate->IsValidLowLevel() && self->py_delegate->IsRooted()) {
13-
self->py_delegate->RemoveFromRoot();
14-
}
1514
Py_TYPE(self)->tp_free((PyObject *)self);
1615
}
1716

@@ -46,7 +45,8 @@ static PyTypeObject ue_PyFDelegateHandleType = {
4645
0, /* tp_methods */
4746
};
4847

49-
void ue_python_init_fdelegatehandle(PyObject *ue_module) {
48+
void ue_python_init_fdelegatehandle(PyObject *ue_module)
49+
{
5050
ue_PyFDelegateHandleType.tp_new = PyType_GenericNew;
5151
if (PyType_Ready(&ue_PyFDelegateHandleType) < 0)
5252
return;
@@ -55,44 +55,43 @@ void ue_python_init_fdelegatehandle(PyObject *ue_module) {
5555
PyModule_AddObject(ue_module, "FDelegateHandle", (PyObject *)&ue_PyFDelegateHandleType);
5656
}
5757

58-
PyObject *py_unreal_engine_add_ticker(PyObject * self, PyObject * args) {
58+
PyObject *py_unreal_engine_add_ticker(PyObject * self, PyObject * args)
59+
{
5960

6061
PyObject *py_callable;
6162
float delay = 0;
62-
if (!PyArg_ParseTuple(args, "O|f:add_ticker", &py_callable, &delay)) {
63+
if (!PyArg_ParseTuple(args, "O|f:add_ticker", &py_callable, &delay))
64+
{
6365
return nullptr;
6466
}
6567

6668
if (!PyCallable_Check(py_callable))
6769
return PyErr_Format(PyExc_Exception, "argument is not a callable");
6870

6971
FTickerDelegate ticker_delegate;
70-
UPythonDelegate *py_delegate = NewObject<UPythonDelegate>();
72+
TSharedRef<FPythonSmartDelegate> py_delegate = MakeShareable(new FPythonSmartDelegate);
7173
py_delegate->SetPyCallable(py_callable);
7274

73-
ticker_delegate.BindUObject(py_delegate, &UPythonDelegate::Tick);
74-
75-
// avoid the delegate to be GC'ed
76-
py_delegate->AddToRoot();
75+
ticker_delegate.BindSP(py_delegate, &FPythonSmartDelegate::Tick);
7776

7877
FDelegateHandle dhandle = FTicker::GetCoreTicker().AddTicker(ticker_delegate, delay);
7978
ue_PyFDelegateHandle *ret = (ue_PyFDelegateHandle *)PyObject_New(ue_PyFDelegateHandle, &ue_PyFDelegateHandleType);
80-
if (!ret) {
79+
if (!ret)
80+
{
8181
FTicker::GetCoreTicker().RemoveTicker(dhandle);
82-
py_delegate->RemoveFromRoot();
8382
return PyErr_Format(PyExc_Exception, "unable to allocate FDelegateHandle python object");
8483
}
8584
ret->dhandle = dhandle;
86-
ret->py_delegate = py_delegate;
8785
ret->garbaged = false;
88-
8986
return (PyObject *)ret;
9087
}
9188

92-
PyObject *py_unreal_engine_remove_ticker(PyObject * self, PyObject * args) {
89+
PyObject *py_unreal_engine_remove_ticker(PyObject * self, PyObject * args)
90+
{
9391

9492
PyObject *py_obj;
95-
if (!PyArg_ParseTuple(args, "O:remove_ticker", &py_obj)) {
93+
if (!PyArg_ParseTuple(args, "O:remove_ticker", &py_obj))
94+
{
9695
return NULL;
9796
}
9897

@@ -101,15 +100,11 @@ PyObject *py_unreal_engine_remove_ticker(PyObject * self, PyObject * args) {
101100

102101
ue_PyFDelegateHandle *py_handle = (ue_PyFDelegateHandle *)py_obj;
103102

104-
if (!py_handle->garbaged) {
103+
if (!py_handle->garbaged)
104+
{
105105
FTicker::GetCoreTicker().RemoveTicker(py_handle->dhandle);
106106
py_handle->garbaged = true;
107107
}
108108

109-
if (py_handle->py_delegate) {
110-
py_handle->py_delegate->RemoveFromRoot();
111-
py_handle->py_delegate = nullptr;
112-
}
113-
114109
Py_RETURN_NONE;
115110
}

Source/UnrealEnginePython/Private/UEPyTicker.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ typedef struct {
88
PyObject_HEAD
99
/* Type-specific fields go here. */
1010
FDelegateHandle dhandle;
11-
UPythonDelegate *py_delegate;
1211
bool garbaged;
1312
} ue_PyFDelegateHandle;
1413

Source/UnrealEnginePython/Private/UnrealEnginePythonPrivatePCH.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#pragma once
44

5-
//#define UEPY_MEMORY_DEBUG 1
5+
#define UEPY_MEMORY_DEBUG 1
66
//#define UEPY_THREADING 1
77

88
#include "UnrealEnginePython.h"

0 commit comments

Comments
 (0)