Skip to content

Commit 760b722

Browse files
author
Roberto De Ioris
committed
preliminaty support for functions
1 parent db01c0e commit 760b722

File tree

2 files changed

+91
-4
lines changed

2 files changed

+91
-4
lines changed

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,70 @@ static PyObject *py_ue_find_object(ue_PyUObject * self, PyObject * args) {
729729
return Py_None;
730730
}
731731

732+
static PyObject *py_ue_find_function(ue_PyUObject * self, PyObject * args) {
733+
734+
ue_py_check(self);
735+
736+
char *name;
737+
if (!PyArg_ParseTuple(args, "s:find_function", &name)) {
738+
return NULL;
739+
}
740+
741+
UFunction *function = self->ue_object->FindFunction(FName(UTF8_TO_TCHAR(name)));
742+
if (!function)
743+
goto end;
744+
745+
UE_LOG(LogPython, Warning, TEXT("Func %d %d"), function->NumParms, function->ReturnValueOffset);
746+
747+
ue_PyUObject *ret = ue_get_python_wrapper((UObject *)function);
748+
if (!ret)
749+
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state");
750+
Py_INCREF(ret);
751+
return (PyObject *)ret;
752+
753+
end:
754+
Py_INCREF(Py_None);
755+
return Py_None;
756+
}
757+
758+
static PyObject *py_ue_call_function(ue_PyUObject * self, PyObject * args) {
759+
760+
ue_py_check(self);
761+
762+
UFunction *function = nullptr;
763+
764+
if (PyTuple_Size(args) < 1) {
765+
return PyErr_Format(PyExc_TypeError, "this function requires at least an argument");
766+
}
767+
768+
PyObject *func_id = PyTuple_GetItem(args, 0);
769+
770+
if (PyUnicode_Check(func_id)) {
771+
function = self->ue_object->FindFunction(FName(UTF8_TO_TCHAR(PyUnicode_AsUTF8(func_id))));
772+
}
773+
774+
775+
if (!function)
776+
return PyErr_Format(PyExc_Exception, "unable to find function");
777+
778+
UE_LOG(LogPython, Warning, TEXT("Func %d %d %d"), function->NumParms, function->ReturnValueOffset, function->ParmsSize);
779+
780+
uint8 *buffer = (uint8 *)FMemory_Alloca(function->ParmsSize);
781+
782+
self->ue_object->ProcessEvent(function, buffer);
783+
784+
TFieldIterator<UProperty> Props(function);
785+
for (; Props; ++Props) {
786+
UProperty *prop = *Props;
787+
if (prop->GetPropertyFlags() & CPF_ReturnParm) {
788+
return ue_py_convert_property(prop, buffer);
789+
}
790+
}
791+
792+
Py_INCREF(Py_None);
793+
return Py_None;
794+
}
795+
732796
#if WITH_EDITOR
733797
static PyObject *py_ue_find_actor_by_label(ue_PyUObject * self, PyObject * args) {
734798

@@ -1037,12 +1101,12 @@ static PyObject *py_ue_get_hit_result_under_cursor(ue_PyUObject * self, PyObject
10371101
}
10381102

10391103
APlayerController *controller = world->GetFirstPlayerController();
1040-
1104+
10411105
if (!controller)
10421106
return PyErr_Format(PyExc_Exception, "unable to find first player controller");
1043-
1107+
10441108
FHitResult hit;
1045-
1109+
10461110
bool got_hit = controller->GetHitResultUnderCursor((ECollisionChannel)channel, complex, hit);
10471111

10481112
if (got_hit) {
@@ -1087,6 +1151,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
10871151
{ "find_actor_by_label", (PyCFunction)py_ue_find_actor_by_label, METH_VARARGS, "" },
10881152
#endif
10891153
{ "find_object", (PyCFunction)py_ue_find_object, METH_VARARGS, "" },
1154+
{ "find_function", (PyCFunction)py_ue_find_function, METH_VARARGS, "" },
1155+
{ "call_function", (PyCFunction)py_ue_call_function, METH_VARARGS, "" },
10901156
{ "all_objects", (PyCFunction)py_ue_all_objects, METH_VARARGS, "" },
10911157
{ "all_actors", (PyCFunction)py_ue_all_actors, METH_VARARGS, "" },
10921158
{ "get_input_axis", (PyCFunction)py_ue_get_input_axis, METH_VARARGS, "" },
@@ -1552,3 +1618,23 @@ UWorld *ue_get_uworld(ue_PyUObject *py_obj) {
15521618
return nullptr;
15531619
}
15541620

1621+
PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer) {
1622+
if (auto casted_prop = Cast<UBoolProperty>(prop)) {
1623+
bool value = casted_prop->GetPropertyValue_InContainer(buffer);
1624+
if (value) {
1625+
Py_INCREF(Py_True);
1626+
return Py_True;
1627+
}
1628+
Py_INCREF(Py_False);
1629+
return Py_False;
1630+
}
1631+
1632+
if (auto casted_prop = Cast<UFloatProperty>(prop)) {
1633+
float value = casted_prop->GetPropertyValue_InContainer(buffer);
1634+
return PyFloat_FromDouble(value);
1635+
}
1636+
1637+
1638+
Py_INCREF(Py_None);
1639+
return Py_None;
1640+
}

Source/UnrealEnginePython/Private/UEPyModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ class UPyObject : public UObject
2222

2323
void unreal_engine_py_log_error();
2424
ue_PyUObject *ue_get_python_wrapper(UObject *);
25-
UWorld *ue_get_uworld(ue_PyUObject *);
25+
UWorld *ue_get_uworld(ue_PyUObject *);
26+
PyObject *ue_py_convert_property(UProperty *, uint8 *);

0 commit comments

Comments
 (0)