Skip to content

Commit 4d28b90

Browse files
committed
fixes from modus
1 parent a62627d commit 4d28b90

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

Content/Scripts/fm/subclassing.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,38 @@
1111
'''
1212
from . common import *
1313
import _fmsubclassing as fms
14+
import types
1415
from unreal_engine import classes as engine_classes
1516

17+
# Define the flags you can use with the ufunction decorator - see Runtime\CoreUObject\Public\UObject\Script.h to add more
18+
class FuncFlag(int): pass
19+
Event = FuncFlag(0x00000800 | 0x08000000)
20+
Static = FuncFlag(0x00002000)
21+
Reliable = FuncFlag(0x00000080)
22+
Multicast = FuncFlag(0x00004000)
23+
Server = FuncFlag(0x00200000)
24+
Client = FuncFlag(0x01000000)
25+
Pure = BlueprintPure = FuncFlag(0x10000000)
26+
1627
# decorator that is roughly equivalent to UFUNCTION() in C++ - use this on a method in a subclass to cause it to
17-
# be exposed as callable
18-
# TODO: add support for pure=True, etc.
19-
def ufunction(f):
20-
f.ufunction = True
21-
return f
28+
# be exposed as callable. Anything the decorator is used on is automatically marked as native, public, and BlueprintCallable,
29+
# so those flags are never needed. The decorator can be used in two ways:
30+
# @ufunction
31+
# @ufunction(...one or more FuncFlags...)
32+
def ufunction(f, *args):
33+
if isinstance(f, types.FunctionType):
34+
# Used without params
35+
assert not args, args
36+
f.ufunc_flags = () # the presence of this function member is enough
37+
return f
38+
else:
39+
# With params
40+
def wrap(f):
41+
for arg in args:
42+
assert isinstance(arg, FuncFlag), 'Invalid ufunction param %s for %s' % (arg, f)
43+
f.ufunc_flags = args
44+
return f
45+
return wrap
2246

2347
# used for declaring UPROPERTYs. Use when creating class vars: myVar = uproperty(FVector, FVector(1,2,3)). By default, implies BlueprintReadWrite.
2448
# TODO: add support for replication, editanywhere, BPReadOnly, repnotify, and other flags. myVar = uproperty(default, *kwFlags)
@@ -133,16 +157,23 @@ def ProcessBridgeDescendentClassMethods(metaclass, newPyClass):
133157
for k,v in list(newPyClass.__dict__.items()):
134158
if k.startswith('__') or k in ('engineClass',):
135159
continue
136-
if not callable(v) or not getattr(v, 'ufunction', None):
160+
if not callable(v):
161+
continue
162+
flags = getattr(v, 'ufunc_flags', None)
163+
if flags is None:
137164
continue
138165
funcName, func = k,v
139166

167+
funcFlags = 0
168+
for flag in flags:
169+
funcFlags |= flag
170+
140171
# Add the method to the class but under a different name so it doesn't get stomped by the stuff below
141172
hiddenFuncName = '_orig_' + funcName
142173
setattr(newPyClass, hiddenFuncName, func)
143174

144175
# Expose a UFUNCTION in C++ that calls this method
145-
fms.add_ufunction(newPyClass.engineClass, funcName, func)
176+
fms.add_ufunction(newPyClass.engineClass, funcName, func, funcFlags)
146177

147178
# Make it so that from Python you can use that name to call the UFUNCTION version in UE4 (so that things
148179
# like replication work)

Source/UnrealEnginePython/Private/FMModule.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,15 @@ static PyObject *add_ufunction(PyObject *self, PyObject *args)
309309
PyObject *pyEngineClass;
310310
char *funcName;
311311
PyObject *pyFunc;
312-
if (!PyArg_ParseTuple(args, "OsO", &pyEngineClass, &funcName, &pyFunc))
312+
unsigned int extraFlags;
313+
if (!PyArg_ParseTuple(args, "OsOI", &pyEngineClass, &funcName, &pyFunc, &extraFlags))
313314
return NULL;
314315

315316
UClass *engineClass = ue_py_check_type<UClass>(pyEngineClass);
316317
if (!engineClass)
317318
return PyErr_Format(PyExc_Exception, "Provide the UClass to attach the function to");
318319

319-
// TODO: compute correct set of function flags
320-
uint32 funcFlags = FUNC_Native | FUNC_BlueprintCallable | FUNC_Public;
320+
uint32 funcFlags = FUNC_Native | FUNC_BlueprintCallable | FUNC_Public | extraFlags;
321321
UPythonFunction *newFunc = (UPythonFunction *)unreal_engine_add_function(engineClass, funcName, pyFunc, funcFlags);
322322
if (newFunc)
323323
{

0 commit comments

Comments
 (0)