@@ -10,6 +10,7 @@ APyCharacter::APyCharacter()
1010 PythonTickForceDisabled = false ;
1111 PythonDisableAutoBinding = false ;
1212
13+ FScopePythonGIL gil;
1314 // pre-generate PyUObject (for performance)
1415 ue_get_python_wrapper (this );
1516}
@@ -18,13 +19,17 @@ APyCharacter::APyCharacter()
1819// Called when the game starts
1920void APyCharacter::BeginPlay ()
2021{
22+
23+
2124 Super::BeginPlay ();
2225
2326 // ...
2427
2528 if (PythonModule.IsEmpty ())
2629 return ;
2730
31+ FScopePythonGIL gil;
32+
2833 PyObject *py_character_module = PyImport_ImportModule (TCHAR_TO_UTF8 (*PythonModule));
2934 if (!py_character_module) {
3035 unreal_engine_py_log_error ();
@@ -92,11 +97,15 @@ void APyCharacter::BeginPlay()
9297// Called every frame
9398void APyCharacter::Tick (float DeltaTime)
9499{
100+
101+
95102 Super::Tick (DeltaTime);
96103
97104 if (!py_character_instance)
98105 return ;
99106
107+ FScopePythonGIL gil;
108+
100109 // no need to check for method availability, we did it in begin_play
101110
102111 PyObject *ret = PyObject_CallMethod (py_character_instance, " tick" , " f" , DeltaTime);
@@ -110,9 +119,13 @@ void APyCharacter::Tick(float DeltaTime)
110119
111120void APyCharacter::CallPyCharacterMethod (FString method_name, FString args)
112121{
122+
123+
113124 if (!py_character_instance)
114125 return ;
115126
127+ FScopePythonGIL gil;
128+
116129 PyObject *ret = nullptr ;
117130 if (args.IsEmpty ()) {
118131 ret = PyObject_CallMethod (py_character_instance, TCHAR_TO_UTF8 (*method_name), NULL );
@@ -130,9 +143,13 @@ void APyCharacter::CallPyCharacterMethod(FString method_name, FString args)
130143
131144void APyCharacter::SetPythonAttrObject (FString attr, UObject *object)
132145{
146+
147+
133148 if (!py_character_instance)
134149 return ;
135150
151+ FScopePythonGIL gil;
152+
136153 ue_PyUObject *py_obj = ue_get_python_wrapper (object);
137154 if (!py_obj) {
138155 PyErr_Format (PyExc_Exception, " PyUObject is in invalid state" );
@@ -147,58 +164,82 @@ void APyCharacter::SetPythonAttrObject(FString attr, UObject *object)
147164
148165void APyCharacter::SetPythonAttrString (FString attr, FString s)
149166{
167+
168+
150169 if (!py_character_instance)
151170 return ;
152171
172+ FScopePythonGIL gil;
173+
153174 if (PyObject_SetAttrString (py_character_instance, TCHAR_TO_UTF8 (*attr), PyUnicode_FromString (TCHAR_TO_UTF8 (*s))) < 0 ) {
154175 UE_LOG (LogPython, Error, TEXT (" Unable to set attribute %s" ), *attr);
155176 }
156177}
157178
158179void APyCharacter::SetPythonAttrFloat (FString attr, float f)
159180{
181+
182+
160183 if (!py_character_instance)
161184 return ;
162185
186+ FScopePythonGIL gil;
187+
163188 if (PyObject_SetAttrString (py_character_instance, TCHAR_TO_UTF8 (*attr), PyFloat_FromDouble (f)) < 0 ) {
164189 UE_LOG (LogPython, Error, TEXT (" Unable to set attribute %s" ), *attr);
165190 }
166191}
167192
168193void APyCharacter::SetPythonAttrInt (FString attr, int n)
169194{
195+
196+
170197 if (!py_character_instance)
171198 return ;
172199
200+ FScopePythonGIL gil;
201+
173202 if (PyObject_SetAttrString (py_character_instance, TCHAR_TO_UTF8 (*attr), PyLong_FromLong (n)) < 0 ) {
174203 UE_LOG (LogPython, Error, TEXT (" Unable to set attribute %s" ), *attr);
175204 }
176205}
177206
178207void APyCharacter::SetPythonAttrVector (FString attr, FVector vec)
179208{
209+
210+
180211 if (!py_character_instance)
181212 return ;
182213
214+ FScopePythonGIL gil;
215+
183216 if (PyObject_SetAttrString (py_character_instance, TCHAR_TO_UTF8 (*attr), py_ue_new_fvector (vec)) < 0 ) {
184217 UE_LOG (LogPython, Error, TEXT (" Unable to set attribute %s" ), *attr);
185218 }
186219}
187220
188221void APyCharacter::SetPythonAttrRotator (FString attr, FRotator rot)
189222{
223+
224+
190225 if (!py_character_instance)
191226 return ;
192227
228+ FScopePythonGIL gil;
229+
193230 if (PyObject_SetAttrString (py_character_instance, TCHAR_TO_UTF8 (*attr), py_ue_new_frotator (rot)) < 0 ) {
194231 UE_LOG (LogPython, Error, TEXT (" Unable to set attribute %s" ), *attr);
195232 }
196233}
197234
198235void APyCharacter::SetPythonAttrBool (FString attr, bool b)
199236{
237+
238+
200239 if (!py_character_instance)
201240 return ;
241+
242+ FScopePythonGIL gil;
202243
203244 PyObject *py_bool = Py_False;
204245 if (b) {
@@ -212,9 +253,13 @@ void APyCharacter::SetPythonAttrBool(FString attr, bool b)
212253
213254bool APyCharacter::CallPyCharacterMethodBool (FString method_name, FString args)
214255{
256+
257+
215258 if (!py_character_instance)
216259 return false ;
217260
261+ FScopePythonGIL gil;
262+
218263 PyObject *ret = nullptr ;
219264 if (args.IsEmpty ()) {
220265 ret = PyObject_CallMethod (py_character_instance, TCHAR_TO_UTF8 (*method_name), NULL );
@@ -240,9 +285,13 @@ bool APyCharacter::CallPyCharacterMethodBool(FString method_name, FString args)
240285
241286float APyCharacter::CallPyCharacterMethodFloat (FString method_name, FString args)
242287{
288+
289+
243290 if (!py_character_instance)
244291 return false ;
245292
293+ FScopePythonGIL gil;
294+
246295 PyObject *ret = nullptr ;
247296 if (args.IsEmpty ()) {
248297 ret = PyObject_CallMethod (py_character_instance, TCHAR_TO_UTF8 (*method_name), NULL );
@@ -271,9 +320,13 @@ float APyCharacter::CallPyCharacterMethodFloat(FString method_name, FString args
271320
272321FString APyCharacter::CallPyCharacterMethodString (FString method_name, FString args)
273322{
323+
324+
274325 if (!py_character_instance)
275326 return FString ();
276327
328+ FScopePythonGIL gil;
329+
277330 PyObject *ret = nullptr ;
278331 if (args.IsEmpty ()) {
279332 ret = PyObject_CallMethod (py_character_instance, TCHAR_TO_UTF8 (*method_name), NULL );
@@ -312,6 +365,7 @@ void APyCharacter::SetupPlayerInputComponent(class UInputComponent* input)
312365
313366APyCharacter::~APyCharacter ()
314367{
368+ FScopePythonGIL gil;
315369#if UEPY_MEMORY_DEBUG
316370 if (py_character_instance && py_character_instance->ob_refcnt != 1 ) {
317371 UE_LOG (LogPython, Error, TEXT (" Inconsistent Python ACharacter wrapper refcnt = %d" ), py_character_instance->ob_refcnt );
0 commit comments