Skip to content

Commit acfb20f

Browse files
author
Roberto De Ioris
committed
improved delegates
1 parent cb19b38 commit acfb20f

File tree

4 files changed

+62
-18
lines changed

4 files changed

+62
-18
lines changed

Source/UnrealEnginePython/Private/UEPyEditor.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,18 +1476,12 @@ PyObject *py_unreal_engine_blueprint_add_function(PyObject * self, PyObject * ar
14761476
char *name;
14771477
if (!PyArg_ParseTuple(args, "Os:blueprint_add_function", &py_blueprint, &name))
14781478
{
1479-
return NULL;
1480-
}
1481-
1482-
if (!ue_is_pyuobject(py_blueprint))
1483-
{
1484-
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
1479+
return nullptr;
14851480
}
1486-
1487-
ue_PyUObject *py_obj = (ue_PyUObject *)py_blueprint;
1488-
if (!py_obj->ue_object->IsA<UBlueprint>())
1489-
return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint");
1490-
UBlueprint *bp = (UBlueprint *)py_obj->ue_object;
1481+
1482+
UBlueprint *bp = ue_py_check_type<UBlueprint>(py_blueprint);
1483+
if (!bp)
1484+
return PyErr_Format(PyExc_Exception, "argument is not a UBlueprint");
14911485

14921486
UEdGraph *graph = FBlueprintEditorUtils::CreateNewGraph(bp, FName(UTF8_TO_TCHAR(name)), UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
14931487
FBlueprintEditorUtils::AddFunctionGraph<UClass>(bp, graph, true, nullptr);

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
540540
{ "set_name", (PyCFunction)py_ue_set_name, METH_VARARGS, "" },
541541

542542
{ "bind_event", (PyCFunction)py_ue_bind_event, METH_VARARGS, "" },
543+
{ "delegate_bind_ufunction", (PyCFunction)py_ue_delegate_bind_ufunction, METH_VARARGS, "" },
543544

544545
{ "get_py_proxy", (PyCFunction)py_ue_get_py_proxy, METH_VARARGS, "" },
545546

@@ -1129,9 +1130,9 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
11291130
#else
11301131
return PyLong_FromLong(u_enum->FindEnumIndex(item.Key));
11311132
#endif
1133+
}
11321134
}
11331135
}
1134-
}
11351136
#endif
11361137
if (self->ue_object->IsA<UEnum>())
11371138
{
@@ -1143,16 +1144,16 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
11431144
return PyLong_FromLong(u_enum->FindEnumIndex(FName(UTF8_TO_TCHAR(attr))));
11441145
#endif
11451146
}
1146-
}
1147+
}
11471148

11481149
if (function)
11491150
{
11501151
// swallow previous exception
11511152
PyErr_Clear();
11521153
return py_ue_new_callable(function, self->ue_object);
11531154
}
1155+
}
11541156
}
1155-
}
11561157
return ret;
11571158
}
11581159

@@ -1723,7 +1724,7 @@ void unreal_engine_py_log_error()
17231724
if (zero)
17241725
{
17251726
msg = PyBytes_AsString(zero);
1726-
}
1727+
}
17271728
#else
17281729
msg = PyString_AsString(PyObject_Str(value));
17291730
#endif
@@ -1778,7 +1779,7 @@ void unreal_engine_py_log_error()
17781779
}
17791780

17801781
PyErr_Clear();
1781-
}
1782+
}
17821783

17831784
// retrieve a UWorld from a generic UObject (if possible)
17841785
UWorld *ue_get_uworld(ue_PyUObject *py_obj)
@@ -1974,6 +1975,11 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index)
19741975
Py_RETURN_UOBJECT(casted_prop);
19751976
}
19761977

1978+
if (auto casted_prop = Cast<UDelegateProperty>(prop))
1979+
{
1980+
Py_RETURN_UOBJECT(casted_prop);
1981+
}
1982+
19771983
if (auto casted_prop = Cast<UArrayProperty>(prop))
19781984
{
19791985
FScriptArrayHelper_InContainer array_helper(casted_prop, buffer, index);
@@ -2677,10 +2683,10 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *
26772683
#else
26782684
prop->ImportText(*default_key_value, prop->ContainerPtrToValuePtr<uint8>(buffer), PPF_Localized, NULL);
26792685
#endif
2680-
}
2686+
}
26812687
#endif
2688+
}
26822689
}
2683-
}
26842690

26852691

26862692
Py_ssize_t tuple_len = PyTuple_Size(args);
@@ -2820,6 +2826,17 @@ PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_
28202826
// re-assign multicast delegate
28212827
casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, multiscript_delegate);
28222828
}
2829+
else if (auto casted_prop = Cast<UDelegateProperty>(u_property))
2830+
{
2831+
2832+
FScriptDelegate script_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object);
2833+
UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop->SignatureFunction);
2834+
// fake UFUNCTION for bypassing checks
2835+
script_delegate.BindUFunction(py_delegate, FName("PyFakeCallable"));
2836+
2837+
// re-assign multicast delegate
2838+
casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, script_delegate);
2839+
}
28232840
else
28242841
{
28252842
if (fail_on_wrong_property)

Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,38 @@ PyObject *py_ue_bind_event(ue_PyUObject * self, PyObject * args)
12321232
return ue_bind_pyevent(self, FString(event_name), py_callable, true);
12331233
}
12341234

1235+
PyObject *py_ue_delegate_bind_ufunction(ue_PyUObject * self, PyObject * args)
1236+
{
1237+
ue_py_check(self);
1238+
1239+
char *delegate_name;
1240+
PyObject *py_obj;
1241+
char *fname;
1242+
1243+
if (!PyArg_ParseTuple(args, "sOs:delegate_bind_ufunction", &delegate_name, &py_obj, &fname))
1244+
return nullptr;
1245+
1246+
UProperty *u_property = self->ue_object->GetClass()->FindPropertyByName(FName(delegate_name));
1247+
if (!u_property)
1248+
return PyErr_Format(PyExc_Exception, "unable to find property %s", delegate_name);
1249+
1250+
UDelegateProperty *Prop = Cast<UDelegateProperty>(u_property);
1251+
if (!Prop)
1252+
return PyErr_Format(PyExc_Exception, "property is not a UDelegateProperty");
1253+
1254+
UObject *Object = ue_py_check_type<UObject>(py_obj);
1255+
if (!Object)
1256+
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
1257+
1258+
FScriptDelegate script_delegate;
1259+
script_delegate.BindUFunction(Object, FName(fname));
1260+
1261+
// re-assign multicast delegate
1262+
Prop->SetPropertyValue_InContainer(self->ue_object, script_delegate);
1263+
1264+
Py_RETURN_NONE;
1265+
}
1266+
12351267
#if PY_MAJOR_VERSION >= 3
12361268
PyObject *py_ue_add_function(ue_PyUObject * self, PyObject * args)
12371269
{

Source/UnrealEnginePython/Private/UObject/UEPyObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ PyObject *py_ue_class_get_flags(ue_PyUObject *, PyObject *);
7272
PyObject *py_ue_class_set_flags(ue_PyUObject *, PyObject *);
7373
PyObject *py_ue_get_obj_flags(ue_PyUObject *, PyObject *);
7474
PyObject *py_ue_set_obj_flags(ue_PyUObject *, PyObject *);
75+
PyObject *py_ue_delegate_bind_ufunction(ue_PyUObject *, PyObject *);
7576

7677

7778
#if WITH_EDITOR

0 commit comments

Comments
 (0)