Skip to content

Commit e32514d

Browse files
author
Roberto De Ioris
committed
added event_dispatchers and pins creation, introduction of a new template based api
1 parent e9fac5c commit e32514d

6 files changed

Lines changed: 128 additions & 9 deletions

File tree

‎Source/UnrealEnginePython/Private/UEPyEdGraph.cpp‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,4 +378,46 @@ PyObject *py_ue_node_find_pin(ue_PyUObject * self, PyObject * args) {
378378
Py_INCREF(ret);
379379
return ret;
380380
}
381+
382+
PyObject *py_ue_node_create_pin(ue_PyUObject * self, PyObject * args) {
383+
384+
ue_py_check(self);
385+
386+
int pin_direction;
387+
PyObject *pin_type;
388+
char *name = nullptr;
389+
int index = 0;
390+
if (!PyArg_ParseTuple(args, "iOs|i:node_create_pin", &pin_direction, &pin_type, &name, &index)) {
391+
return nullptr;
392+
}
393+
394+
UEdGraphNode *node = ue_py_check_type<UEdGraphNode>(self);
395+
if (!node)
396+
return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraphNode");
397+
398+
FEdGraphPinType *pin_struct = ue_py_check_struct<FEdGraphPinType>(pin_type);
399+
if (!pin_type)
400+
return PyErr_Format(PyExc_Exception, "argument is not a FEdGraphPinType");
401+
402+
UEdGraphPin *pin = nullptr;
403+
404+
if (node->IsA<UK2Node_EditablePinBase>()) {
405+
UK2Node_EditablePinBase *node_base = (UK2Node_EditablePinBase *)node;
406+
pin = node_base->CreateUserDefinedPin(UTF8_TO_TCHAR(name), *pin_struct, (EEdGraphPinDirection)pin_direction);
407+
}
408+
else {
409+
pin = node->CreatePin((EEdGraphPinDirection)pin_direction, *pin_struct, UTF8_TO_TCHAR(name), index);
410+
}
411+
if (!pin) {
412+
return PyErr_Format(PyExc_Exception, "unable to create pin \"%s\"", name);
413+
}
414+
415+
if (UBlueprint *bp = Cast<UBlueprint>(node->GetGraph()->GetOuter())) {
416+
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
417+
}
418+
419+
PyObject *ret = py_ue_new_edgraphpin(pin);
420+
Py_INCREF(ret);
421+
return ret;
422+
}
381423
#endif

‎Source/UnrealEnginePython/Private/UEPyEdGraph.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ PyObject *py_ue_graph_get_good_place_for_new_node(ue_PyUObject *, PyObject *);
1616

1717
PyObject *py_ue_node_pins(ue_PyUObject *, PyObject *);
1818
PyObject *py_ue_node_find_pin(ue_PyUObject *, PyObject *);
19+
PyObject *py_ue_node_create_pin(ue_PyUObject *, PyObject *);
1920
#endif

‎Source/UnrealEnginePython/Private/UEPyEditor.cpp‎

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,6 @@ PyObject *py_unreal_engine_add_component_to_blueprint(PyObject * self, PyObject
970970
bp->SimpleConstructionScript->AddNode(node);
971971
}
972972

973-
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
974-
975973
ue_PyUObject *ret = ue_get_python_wrapper(node->ComponentTemplate);
976974
if (!ret)
977975
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
@@ -1104,6 +1102,53 @@ PyObject *py_unreal_engine_blueprint_add_function(PyObject * self, PyObject * ar
11041102
return ret;
11051103
}
11061104

1105+
PyObject *py_unreal_engine_blueprint_add_event_dispatcher(PyObject * self, PyObject * args) {
1106+
1107+
PyObject *py_blueprint;
1108+
char *name;
1109+
if (!PyArg_ParseTuple(args, "Os:blueprint_add_event_dispatcher", &py_blueprint, &name)) {
1110+
return NULL;
1111+
}
1112+
1113+
UBlueprint *bp = ue_py_check_type<UBlueprint>(py_blueprint);
1114+
if (!bp)
1115+
return PyErr_Format(PyExc_Exception, "argument is not a UBlueprint");
1116+
1117+
FName multicast_name = FName(UTF8_TO_TCHAR(name));
1118+
1119+
bp->Modify();
1120+
1121+
const UEdGraphSchema_K2 *state = GetDefault<UEdGraphSchema_K2>();
1122+
1123+
FEdGraphPinType multicast_type;
1124+
multicast_type.PinCategory = state->PC_MCDelegate;
1125+
1126+
if (!FBlueprintEditorUtils::AddMemberVariable(bp, multicast_name, multicast_type)) {
1127+
return PyErr_Format(PyExc_Exception, "unable to create multicast variable");
1128+
}
1129+
1130+
UEdGraph *graph = FBlueprintEditorUtils::CreateNewGraph(bp, multicast_name, UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
1131+
if (!graph) {
1132+
return PyErr_Format(PyExc_Exception, "unable to create graph");
1133+
}
1134+
1135+
graph->bEditable = false;
1136+
1137+
state->CreateDefaultNodesForGraph(*graph);
1138+
state->CreateFunctionGraphTerminators(*graph, (UClass *)nullptr);
1139+
state->AddExtraFunctionFlags(graph, (FUNC_BlueprintCallable | FUNC_BlueprintEvent | FUNC_Public));
1140+
state->MarkFunctionEntryAsEditable(graph, true);
1141+
1142+
bp->DelegateSignatureGraphs.Add(graph);
1143+
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
1144+
1145+
PyObject *ret = (PyObject *)ue_get_python_wrapper(graph);
1146+
if (!ret)
1147+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
1148+
Py_INCREF(ret);
1149+
return ret;
1150+
}
1151+
11071152
PyObject *py_unreal_engine_blueprint_add_ubergraph_page(PyObject * self, PyObject * args) {
11081153

11091154
PyObject *py_blueprint;
@@ -1145,7 +1190,7 @@ PyObject *py_unreal_engine_create_new_graph(PyObject * self, PyObject * args) {
11451190
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
11461191
}
11471192
ue_PyUObject *py_obj = (ue_PyUObject *)py_object;
1148-
1193+
11491194
if (!ue_is_pyuobject(py_graph_class)) {
11501195
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
11511196
}

‎Source/UnrealEnginePython/Private/UEPyEditor.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ PyObject *py_unreal_engine_move_selected_actors_to_level(PyObject *, PyObject *)
5858
PyObject *py_ue_factory_create_new(ue_PyUObject *, PyObject *);
5959
PyObject *py_ue_factory_import_object(ue_PyUObject *, PyObject *);
6060

61+
PyObject *py_unreal_engine_blueprint_add_event_dispatcher(PyObject *, PyObject *);
62+
6163
PyObject *py_unreal_engine_editor_take_high_res_screen_shots(PyObject *, PyObject *);
6264

6365
PyObject *py_unreal_engine_blueprint_add_function(PyObject *, PyObject *);

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ static PyMethodDef unreal_engine_methods[] = {
184184
{ "reload_blueprint", py_unreal_engine_reload_blueprint, METH_VARARGS, "" },
185185
{ "compile_blueprint", py_unreal_engine_compile_blueprint, METH_VARARGS, "" },
186186
{ "blueprint_add_member_variable", py_unreal_engine_blueprint_add_member_variable, METH_VARARGS, "" },
187+
{ "blueprint_add_event_dispatcher", py_unreal_engine_blueprint_add_event_dispatcher, METH_VARARGS, "" },
187188
{ "blueprint_add_new_timeline", py_unreal_engine_blueprint_add_new_timeline, METH_VARARGS, "" },
188189
{ "blueprint_set_variable_visibility", py_unreal_engine_blueprint_set_variable_visibility, METH_VARARGS, "" },
189190
{ "blueprint_add_function", py_unreal_engine_blueprint_add_function, METH_VARARGS, "" },
@@ -372,6 +373,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
372373

373374
{ "node_pins", (PyCFunction)py_ue_node_pins, METH_VARARGS, "" },
374375
{ "node_find_pin", (PyCFunction)py_ue_node_find_pin, METH_VARARGS, "" },
376+
{ "node_create_pin", (PyCFunction)py_ue_node_create_pin, METH_VARARGS, "" },
375377

376378
{ "get_material_graph", (PyCFunction)py_ue_get_material_graph, METH_VARARGS, "" },
377379
#endif

‎Source/UnrealEnginePython/Private/UEPyModule.h‎

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ typedef struct {
1111
PyObject_HEAD
1212
/* Type-specific fields go here. */
1313
UObject *ue_object;
14-
// reference to proxy class (can be null)
15-
PyObject *py_proxy;
16-
// list of exposed delegates
17-
std::list<UPythonDelegate*> *python_delegates_gc;
18-
// the __dict__
19-
PyObject *py_dict;
14+
// reference to proxy class (can be null)
15+
PyObject *py_proxy;
16+
// list of exposed delegates
17+
std::list<UPythonDelegate*> *python_delegates_gc;
18+
// the __dict__
19+
PyObject *py_dict;
2020
} ue_PyUObject;
2121

2222

@@ -37,3 +37,30 @@ void ue_pydelegates_cleanup(ue_PyUObject *);
3737

3838
UClass *unreal_engine_new_uclass(char *, UClass *);
3939
UFunction *unreal_engine_add_function(UClass *, char *, PyObject *, uint32);
40+
41+
42+
template <typename T> T *ue_py_check_type(PyObject *py_obj) {
43+
ue_PyUObject *ue_py_obj = ue_is_pyuobject(py_obj);
44+
if (!ue_py_obj) {
45+
return nullptr;
46+
}
47+
48+
return Cast<T>(ue_py_obj->ue_object);
49+
}
50+
51+
template <typename T> T *ue_py_check_type(ue_PyUObject *py_obj) {
52+
return Cast<T>(py_obj->ue_object);
53+
}
54+
55+
template <typename T> T *ue_py_check_struct(PyObject *py_obj) {
56+
ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_obj);
57+
if (!ue_py_struct) {
58+
return nullptr;
59+
}
60+
61+
if (ue_py_struct->u_struct == T::StaticStruct()) {
62+
return (T*)ue_py_struct->data;
63+
}
64+
65+
return nullptr;
66+
}

0 commit comments

Comments
 (0)