Skip to content

Commit 817995d

Browse files
author
Roberto De Ioris
committed
Merge branch 'master' into bebylon
2 parents 5bf985d + b3cdb3b commit 817995d

92 files changed

Lines changed: 2268 additions & 146 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Source/UnrealEnginePython/Private/PyActor.cpp‎

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,10 @@ APyActor::APyActor()
1212

1313
}
1414

15-
16-
// Called when the game starts
17-
void APyActor::BeginPlay()
15+
void APyActor::PostInitializeComponents()
1816
{
19-
Super::BeginPlay();
17+
Super::PostInitializeComponents();
2018

21-
// ...
2219

2320
if (PythonModule.IsEmpty())
2421
return;
@@ -67,14 +64,33 @@ void APyActor::BeginPlay()
6764

6865
PyObject_SetAttrString(py_actor_instance, (char*)"uobject", (PyObject *)py_uobject);
6966

70-
7167
if (!PyObject_HasAttrString(py_actor_instance, (char *)"tick") || PythonTickForceDisabled) {
7268
SetActorTickEnabled(false);
7369
}
7470

7571
if (!PythonDisableAutoBinding)
7672
ue_autobind_events_for_pyclass(py_uobject, py_actor_instance);
7773

74+
ue_bind_events_for_py_class_by_attribute(this, py_actor_instance);
75+
76+
if (!PyObject_HasAttrString(py_actor_instance, (char *)"post_initialize_components"))
77+
return;
78+
79+
PyObject *pic_ret = PyObject_CallMethod(py_actor_instance, (char *)"post_initialize_components", NULL);
80+
if (!pic_ret) {
81+
unreal_engine_py_log_error();
82+
return;
83+
}
84+
Py_DECREF(pic_ret);
85+
}
86+
87+
// Called when the game starts
88+
void APyActor::BeginPlay()
89+
{
90+
Super::BeginPlay();
91+
92+
if (!py_actor_instance)
93+
return;
7894

7995
if (!PyObject_HasAttrString(py_actor_instance, (char *)"begin_play"))
8096
return;

‎Source/UnrealEnginePython/Private/PyCharacter.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ void APyCharacter::BeginPlay()
7777
if (!PythonDisableAutoBinding)
7878
ue_autobind_events_for_pyclass(py_uobject, py_character_instance);
7979

80+
ue_bind_events_for_py_class_by_attribute(this, py_character_instance);
81+
8082
if (!PyObject_HasAttrString(py_character_instance, (char *)"begin_play")) {
8183
return;
8284
}
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#include "UnrealEnginePythonPrivatePCH.h"
2+
#include "PyHUD.h"
3+
4+
#include "PythonDelegate.h"
5+
6+
APyHUD::APyHUD()
7+
{
8+
PrimaryActorTick.bCanEverTick = true;
9+
10+
PythonTickForceDisabled = false;
11+
PythonDisableAutoBinding = false;
12+
13+
}
14+
15+
16+
// Called when the game starts
17+
void APyHUD::BeginPlay()
18+
{
19+
Super::BeginPlay();
20+
21+
// ...
22+
23+
if (PythonModule.IsEmpty())
24+
return;
25+
26+
FScopePythonGIL gil;
27+
28+
py_uobject = ue_get_python_wrapper(this);
29+
if (!py_uobject) {
30+
unreal_engine_py_log_error();
31+
return;
32+
}
33+
34+
PyObject *py_hud_module = PyImport_ImportModule(TCHAR_TO_UTF8(*PythonModule));
35+
if (!py_hud_module) {
36+
unreal_engine_py_log_error();
37+
return;
38+
}
39+
40+
#if WITH_EDITOR
41+
// todo implement autoreload with a dictionary of module timestamps
42+
py_hud_module = PyImport_ReloadModule(py_hud_module);
43+
if (!py_hud_module) {
44+
unreal_engine_py_log_error();
45+
return;
46+
}
47+
#endif
48+
49+
if (PythonClass.IsEmpty())
50+
return;
51+
52+
PyObject *py_hud_module_dict = PyModule_GetDict(py_hud_module);
53+
PyObject *py_hud_class = PyDict_GetItemString(py_hud_module_dict, TCHAR_TO_UTF8(*PythonClass));
54+
55+
if (!py_hud_class) {
56+
UE_LOG(LogPython, Error, TEXT("Unable to find class %s in module %s"), *PythonClass, *PythonModule);
57+
return;
58+
}
59+
60+
py_hud_instance = PyObject_CallObject(py_hud_class, NULL);
61+
if (!py_hud_instance) {
62+
unreal_engine_py_log_error();
63+
return;
64+
}
65+
66+
py_uobject->py_proxy = py_hud_instance;
67+
68+
PyObject_SetAttrString(py_hud_instance, (char*)"uobject", (PyObject *)py_uobject);
69+
70+
71+
if (!PyObject_HasAttrString(py_hud_instance, (char *)"tick") || PythonTickForceDisabled) {
72+
SetActorTickEnabled(false);
73+
}
74+
75+
if (!PythonDisableAutoBinding)
76+
ue_autobind_events_for_pyclass(py_uobject, py_hud_instance);
77+
78+
ue_bind_events_for_py_class_by_attribute(this, py_hud_instance);
79+
80+
if (!PyObject_HasAttrString(py_hud_instance, (char *)"begin_play"))
81+
return;
82+
83+
PyObject *bp_ret = PyObject_CallMethod(py_hud_instance, (char *)"begin_play", nullptr);
84+
if (!bp_ret) {
85+
unreal_engine_py_log_error();
86+
return;
87+
}
88+
Py_DECREF(bp_ret);
89+
}
90+
91+
92+
// Called every frame
93+
void APyHUD::Tick(float DeltaTime)
94+
{
95+
Super::Tick(DeltaTime);
96+
97+
if (!py_hud_instance)
98+
return;
99+
100+
FScopePythonGIL gil;
101+
102+
if (!PyObject_HasAttrString(py_hud_instance, (char *)"tick"))
103+
return;
104+
105+
PyObject *ret = PyObject_CallMethod(py_hud_instance, (char *)"tick", (char *)"f", DeltaTime);
106+
if (!ret) {
107+
unreal_engine_py_log_error();
108+
return;
109+
}
110+
Py_DECREF(ret);
111+
112+
}
113+
114+
void APyHUD::DrawHUD()
115+
{
116+
Super::DrawHUD();
117+
118+
if (!py_hud_instance)
119+
return;
120+
121+
FScopePythonGIL gil;
122+
123+
if (!PyObject_HasAttrString(py_hud_instance, (char *)"draw_hud"))
124+
return;
125+
126+
PyObject *ret = PyObject_CallMethod(py_hud_instance, (char *)"draw_hud", nullptr);
127+
if (!ret) {
128+
unreal_engine_py_log_error();
129+
return;
130+
}
131+
Py_DECREF(ret);
132+
133+
}
134+
135+
136+
void APyHUD::CallPythonHUDMethod(FString method_name, FString args)
137+
{
138+
if (!py_hud_instance)
139+
return;
140+
141+
FScopePythonGIL gil;
142+
143+
PyObject *ret = nullptr;
144+
if (args.IsEmpty()) {
145+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), NULL);
146+
}
147+
else {
148+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), (char *)"s", TCHAR_TO_UTF8(*args));
149+
}
150+
151+
if (!ret) {
152+
unreal_engine_py_log_error();
153+
return;
154+
}
155+
Py_DECREF(ret);
156+
}
157+
158+
bool APyHUD::CallPythonHUDMethodBool(FString method_name, FString args)
159+
{
160+
if (!py_hud_instance)
161+
return false;
162+
163+
FScopePythonGIL gil;
164+
165+
PyObject *ret = nullptr;
166+
if (args.IsEmpty()) {
167+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), NULL);
168+
}
169+
else {
170+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), (char *)"s", TCHAR_TO_UTF8(*args));
171+
}
172+
if (!ret) {
173+
unreal_engine_py_log_error();
174+
return false;
175+
}
176+
177+
if (PyObject_IsTrue(ret)) {
178+
Py_DECREF(ret);
179+
return true;
180+
}
181+
182+
Py_DECREF(ret);
183+
return false;
184+
}
185+
186+
FString APyHUD::CallPythonHUDMethodString(FString method_name, FString args)
187+
{
188+
if (!py_hud_instance)
189+
return FString();
190+
191+
FScopePythonGIL gil;
192+
193+
PyObject *ret = nullptr;
194+
if (args.IsEmpty()) {
195+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), NULL);
196+
}
197+
else {
198+
ret = PyObject_CallMethod(py_hud_instance, TCHAR_TO_UTF8(*method_name), (char *)"s", TCHAR_TO_UTF8(*args));
199+
}
200+
if (!ret) {
201+
unreal_engine_py_log_error();
202+
return FString();
203+
}
204+
205+
PyObject *py_str = PyObject_Str(ret);
206+
if (!py_str) {
207+
Py_DECREF(ret);
208+
return FString();
209+
}
210+
211+
char *str_ret = PyUnicode_AsUTF8(py_str);
212+
213+
FString ret_fstring = FString(UTF8_TO_TCHAR(str_ret));
214+
215+
Py_DECREF(py_str);
216+
217+
return ret_fstring;
218+
}
219+
220+
221+
APyHUD::~APyHUD()
222+
{
223+
FScopePythonGIL gil;
224+
225+
ue_pydelegates_cleanup(py_uobject);
226+
227+
#if defined(UEPY_MEMORY_DEBUG)
228+
if (py_hud_instance && py_hud_instance->ob_refcnt != 1) {
229+
UE_LOG(LogPython, Error, TEXT("Inconsistent Python AHUD wrapper refcnt = %d"), py_hud_instance->ob_refcnt);
230+
}
231+
#endif
232+
Py_XDECREF(py_hud_instance);
233+
234+
#if defined(UEPY_MEMORY_DEBUG)
235+
UE_LOG(LogPython, Warning, TEXT("Python AHUD %p (mapped to %p) wrapper XDECREF'ed"), this, py_uobject ? py_uobject->ue_object : nullptr);
236+
#endif
237+
238+
// this could trigger the distruction of the python/uobject mapper
239+
Py_XDECREF(py_uobject);
240+
}

‎Source/UnrealEnginePython/Private/PyPawn.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ void APyPawn::BeginPlay()
7575
if (!PythonDisableAutoBinding)
7676
ue_autobind_events_for_pyclass(py_uobject, py_pawn_instance);
7777

78+
ue_bind_events_for_py_class_by_attribute(this, py_pawn_instance);
79+
7880
if (!PyObject_HasAttrString(py_pawn_instance, (char *)"begin_play"))
7981
return;
8082

0 commit comments

Comments
 (0)