Repository navigation
Expand file tree
/
Copy pathUnrealEnginePython.h
More file actions
226 lines (173 loc) · 5.85 KB
/
Copy pathUnrealEnginePython.h
File metadata and controls
226 lines (173 loc) · 5.85 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright 20Tab S.r.l.
#pragma once
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
#endif
//#define UEPY_MEMORY_DEBUG 1
//#define EXTRA_LOGGING 1
#ifdef EXTRA_LOGGING
#define EXTRA_UE_LOG(log_python, log_level, fmt, args...) \
UE_LOG(log_python, log_level, fmt, ##args)
#define EXTRA_DEBUG_CODE 1
#else
#define EXTRA_UE_LOG(...)
#endif
#include "CoreMinimal.h"
#include "Runtime/Core/Public/Modules/ModuleManager.h"
#include "Runtime/SlateCore/Public/Styling/SlateStyle.h"
#include "UObject/ScriptMacros.h"
#include "Runtime/Launch/Resources/Version.h"
#if PLATFORM_MAC
#include <Headers/Python.h>
#include <Headers/structmember.h>
#elif PLATFORM_LINUX
#include <Python.h>
#include <structmember.h>
#elif PLATFORM_ANDROID
#include <Python.h>
#include <structmember.h>
#elif PLATFORM_WINDOWS
#include <include/pyconfig.h>
#ifndef SIZEOF_PID_T
#define SIZEOF_PID_T 4
#endif
#include <include/Python.h>
#include <include/structmember.h>
#endif
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
UObject *ue_object;
// reference to proxy class (can be null)
PyObject *py_proxy;
// the __dict__
PyObject *py_dict;
// if true RemoveFromRoot will be called at object destruction time
int auto_rooted;
// if owned the life of the UObject is related to the life of PyObject
int owned;
} ue_PyUObject;
UNREALENGINEPYTHON_API void ue_py_register_magic_module(char *name, PyObject *(*)());
UNREALENGINEPYTHON_API PyObject *ue_py_register_module(const char *);
#if ENGINE_MINOR_VERSION >= 18
#define FStringAssetReference FSoftObjectPath
#endif
#define ue_py_check(py_u) if (!FUnrealEnginePythonHouseKeeper::Get()->IsValidPyUObject(py_u))\
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state")
#define ue_py_check_int(py_u) if (!FUnrealEnginePythonHouseKeeper::Get()->IsValidPyUObject(py_u))\
{\
PyErr_SetString(PyExc_Exception, "PyUObject is in invalid state");\
return -1;\
}
const char *UEPyUnicode_AsUTF8(PyObject *py_str);
#if PY_MAJOR_VERSION < 3
int PyGILState_Check();
#endif
bool PyUnicodeOrString_Check(PyObject *py_obj);
UNREALENGINEPYTHON_API void unreal_engine_py_log_error();
UNREALENGINEPYTHON_API ue_PyUObject *ue_get_python_uobject(UObject *);
UNREALENGINEPYTHON_API ue_PyUObject *ue_get_python_uobject_inc(UObject *);
#define Py_RETURN_UOBJECT(py_uobj) ue_PyUObject *ret = ue_get_python_uobject_inc(py_uobj);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");\
return (PyObject *)ret;
#define Py_RETURN_UOBJECT_NOINC(py_uobj) ue_PyUObject *ret = ue_get_python_uobject(py_uobj);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");\
return (PyObject *)ret;
#if ENGINE_MINOR_VERSION >= 25
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
FProperty *ue_fproperty;
// the __dict__
PyObject *py_dict;
//// if true RemoveFromRoot will be called at object destruction time
//int auto_rooted;
//// if owned the life of the UObject is related to the life of PyObject
//int owned;
} ue_PyFProperty;
UNREALENGINEPYTHON_API ue_PyFProperty *ue_get_python_fproperty(FProperty *);
UNREALENGINEPYTHON_API ue_PyFProperty *ue_get_python_fproperty_inc(FProperty *);
#define Py_RETURN_FPROPERTY(py_fprop) ue_PyFProperty *ret = ue_get_python_fproperty_inc(py_fprop);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "fproperty is invalid");\
return (PyObject *)ret;
#define Py_RETURN_FPROPERTY_NOINC(py_fprop) ue_PyFProperty *ret = ue_get_python_fproperty(py_fprop);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "fproperty is invalid");\
return (PyObject *)ret;
// for the moment it seems I need both an FProperty wrap and an FFieldClass wrap
// not sure about this yet
// for uobjects both property and class are the same type ie uobjects which is not true for
// FProperties but havent figured the ramifications of this yet
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
FFieldClass *ue_ffieldclass;
// the __dict__
PyObject *py_dict;
//// if true RemoveFromRoot will be called at object destruction time
//int auto_rooted;
//// if owned the life of the UObject is related to the life of PyObject
//int owned;
} ue_PyFFieldClass;
UNREALENGINEPYTHON_API ue_PyFFieldClass *ue_get_python_ffieldclass(FFieldClass *);
UNREALENGINEPYTHON_API ue_PyFFieldClass *ue_get_python_ffieldclass_inc(FFieldClass *);
#define Py_RETURN_FFIELDCLASS(py_ffieldclass) ue_PyFFieldClass *ret = ue_get_python_ffieldclass_inc(py_ffieldclass);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "ffieldclass is invalid");\
return (PyObject *)ret;
#define Py_RETURN_FFIELDCLASS_NOINC(py_ffieldclass) ue_PyFFieldClass *ret = ue_get_python_ffieldclass(py_ffieldclass);\
if (!ret)\
return PyErr_Format(PyExc_Exception, "ffieldclass is invalid");\
return (PyObject *)ret;
#endif
#if ENGINE_MINOR_VERSION < 16
template<class CPPSTRUCT>
struct TStructOpsTypeTraitsBase2 : TStructOpsTypeTraitsBase
{
};
#endif
DECLARE_LOG_CATEGORY_EXTERN(LogPython, Log, All);
class UNREALENGINEPYTHON_API FUnrealEnginePythonModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
void RunString(char *);
void RunFile(char *);
#if PLATFORM_MAC
void RunStringInMainThread(char *);
void RunFileInMainThread(char *);
#endif
void UESetupPythonInterpreter(bool);
TArray<FString> ScriptsPaths;
FString ZipPath;
FString AdditionalModulesPath;
bool BrutalFinalize;
// pep8ize a string using various strategy (currently only autopep8 is supported)
FString Pep8ize(FString Code);
private:
void *ue_python_gil;
// used by console
void *main_dict;
void *local_dict;
void *main_module;
TSharedPtr<FSlateStyleSet> StyleSet;
};
struct FScopePythonGIL
{
PyGILState_STATE state;
FScopePythonGIL()
{
state = PyGILState_Ensure();
}
~FScopePythonGIL()
{
PyGILState_Release(state);
}
};