Repository navigation
Expand file tree
/
Copy pathPyUserWidget.cpp
More file actions
145 lines (108 loc) · 3.41 KB
/
Copy pathPyUserWidget.cpp
File metadata and controls
145 lines (108 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "UnrealEnginePythonPrivatePCH.h"
#include "PyUserWidget.h"
#include "PythonDelegate.h"
#include "Slate/UEPyFGeometry.h"
bool UPyUserWidget::Initialize()
{
if (!Super::Initialize())
return false;
if (PythonModule.IsEmpty())
return false;
FScopePythonGIL gil;
py_uobject = ue_get_python_wrapper(this);
if (!py_uobject) {
unreal_engine_py_log_error();
return false;
}
PyObject *py_user_widget_module = PyImport_ImportModule(TCHAR_TO_UTF8(*PythonModule));
if (!py_user_widget_module) {
unreal_engine_py_log_error();
return false;
}
#if WITH_EDITOR
// todo implement autoreload with a dictionary of module timestamps
py_user_widget_module = PyImport_ReloadModule(py_user_widget_module);
if (!py_user_widget_module) {
unreal_engine_py_log_error();
return false;
}
#endif
if (PythonClass.IsEmpty())
return false;
PyObject *py_user_widget_module_dict = PyModule_GetDict(py_user_widget_module);
PyObject *py_user_widget_class = PyDict_GetItemString(py_user_widget_module_dict, TCHAR_TO_UTF8(*PythonClass));
if (!py_user_widget_class) {
UE_LOG(LogPython, Error, TEXT("Unable to find class %s in module %s"), *PythonClass, *PythonModule);
return false;
}
py_user_widget_instance = PyObject_CallObject(py_user_widget_class, NULL);
if (!py_user_widget_instance) {
unreal_engine_py_log_error();
return false;
}
py_uobject->py_proxy = py_user_widget_instance;
PyObject_SetAttrString(py_user_widget_instance, (char*)"uobject", (PyObject *)py_uobject);
return true;
}
void UPyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
if (!py_user_widget_instance)
return;
FScopePythonGIL gil;
if (!PyObject_HasAttrString(py_user_widget_instance, (char *)"construct"))
return;
PyObject *bp_ret = PyObject_CallMethod(py_user_widget_instance, (char *)"construct", NULL);
if (!bp_ret) {
unreal_engine_py_log_error();
return;
}
Py_DECREF(bp_ret);
}
void UPyUserWidget::NativeDestruct()
{
Super::NativeDestruct();
if (!py_user_widget_instance)
return;
FScopePythonGIL gil;
if (!PyObject_HasAttrString(py_user_widget_instance, (char *)"destruct"))
return;
PyObject *bp_ret = PyObject_CallMethod(py_user_widget_instance, (char *)"destruct", NULL);
if (!bp_ret) {
unreal_engine_py_log_error();
return;
}
Py_DECREF(bp_ret);
}
// Called every frame
void UPyUserWidget::NativeTick(const FGeometry & MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
if (!py_user_widget_instance)
return;
FScopePythonGIL gil;
if (!PyObject_HasAttrString(py_user_widget_instance, (char *)"tick"))
return;
PyObject *ret = PyObject_CallMethod(py_user_widget_instance, (char *)"tick", (char *)"Of", py_ue_new_fgeometry(MyGeometry), InDeltaTime);
if (!ret) {
unreal_engine_py_log_error();
return;
}
Py_DECREF(ret);
}
UPyUserWidget::~UPyUserWidget()
{
FScopePythonGIL gil;
ue_pydelegates_cleanup(py_uobject);
#if defined(UEPY_MEMORY_DEBUG)
if (py_user_widget_instance && py_user_widget_instance->ob_refcnt != 1) {
UE_LOG(LogPython, Error, TEXT("Inconsistent Python UUserWidget wrapper refcnt = %d"), py_user_widget_instance->ob_refcnt);
}
#endif
Py_XDECREF(py_user_widget_instance);
#if defined(UEPY_MEMORY_DEBUG)
UE_LOG(LogPython, Warning, TEXT("Python UUserWidget %p (mapped to %p) wrapper XDECREF'ed"), this, py_uobject ? py_uobject->ue_object : nullptr);
#endif
// this could trigger the distruction of the python/uobject mapper
Py_XDECREF(py_uobject);
}