Skip to content

Commit 40a0958

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 2093ffd + ac19f6a commit 40a0958

28 files changed

Lines changed: 1004 additions & 90 deletions

‎Source/PythonConsole/Private/SPythonLog.cpp‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,14 @@ void SPythonConsoleInputBox::OnTextCommitted(const FText& InText, ETextCommit::T
208208
this->History.Add(ExecString);
209209
this->HistoryPosition = this->History.Num();
210210

211-
UE_LOG(LogTemp, Log, TEXT(">>> %s"), *ExecString);
211+
if (IsMultiline)
212+
{
213+
UE_LOG(LogTemp, Log, TEXT("... %s"), *ExecString);
214+
}
215+
else
216+
{
217+
UE_LOG(LogTemp, Log, TEXT(">>> %s"), *ExecString);
218+
}
212219

213220
// Clear the console input area
214221
bIgnoreUIUpdate = true;

‎Source/UnrealEnginePython/Private/PyUserWidget.cpp‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,28 @@ UPyUserWidget::~UPyUserWidget()
328328
// this could trigger the distruction of the python/uobject mapper
329329
Py_XDECREF(py_uobject);
330330
}
331+
332+
void UPyUserWidget::CallPythonUserWidgetMethod(FString method_name, FString args)
333+
{
334+
if (!py_user_widget_instance)
335+
return;
336+
337+
FScopePythonGIL gil;
338+
339+
PyObject *ret = nullptr;
340+
if (args.IsEmpty())
341+
{
342+
ret = PyObject_CallMethod(py_user_widget_instance, TCHAR_TO_UTF8(*method_name), NULL);
343+
}
344+
else
345+
{
346+
ret = PyObject_CallMethod(py_user_widget_instance, TCHAR_TO_UTF8(*method_name), (char *)"s", TCHAR_TO_UTF8(*args));
347+
}
348+
349+
if (!ret)
350+
{
351+
unreal_engine_py_log_error();
352+
return;
353+
}
354+
Py_DECREF(ret);
355+
}

‎Source/UnrealEnginePython/Private/UEPyEngine.cpp‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ PyObject *py_unreal_engine_string_to_guid(PyObject * self, PyObject * args)
425425
char *str;
426426
if (!PyArg_ParseTuple(args, "s:string_to_guid", &str))
427427
{
428-
return NULL;
428+
return nullptr;
429429
}
430430

431431
FGuid guid;
@@ -444,7 +444,21 @@ PyObject *py_unreal_engine_new_guid(PyObject * self, PyObject * args)
444444
FGuid guid = FGuid::NewGuid();
445445

446446
return py_ue_new_uscriptstruct(FindObject<UScriptStruct>(ANY_PACKAGE, UTF8_TO_TCHAR((char *)"Guid")), (uint8 *)&guid);
447+
}
448+
449+
PyObject *py_unreal_engine_guid_to_string(PyObject * self, PyObject * args)
450+
{
451+
PyObject *py_guid;
452+
if (!PyArg_ParseTuple(args, "O:guid_to_string", &py_guid))
453+
{
454+
return nullptr;
455+
}
456+
457+
FGuid *guid = ue_py_check_fguid(py_guid);
458+
if (!guid)
459+
return PyErr_Format(PyExc_Exception, "object is not a FGuid");
447460

461+
return PyUnicode_FromString(TCHAR_TO_UTF8(*guid->ToString()));
448462
}
449463

450464
PyObject *py_unreal_engine_slate_tick(PyObject * self, PyObject * args)

‎Source/UnrealEnginePython/Private/UEPyEngine.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ PyObject *py_unreal_engine_load_package(PyObject *, PyObject *);
3333

3434
PyObject *py_unreal_engine_string_to_guid(PyObject *, PyObject *);
3535
PyObject *py_unreal_engine_new_guid(PyObject *, PyObject *);
36+
PyObject *py_unreal_engine_guid_to_string(PyObject *, PyObject *);
3637

3738
PyObject *py_unreal_engine_engine_tick(PyObject *, PyObject *);
3839
PyObject *py_unreal_engine_slate_tick(PyObject *, PyObject *);

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "UObject/UEPyAnimSequence.h"
3636
#include "UObject/UEPyCapture.h"
3737
#include "UObject/UEPyLandscape.h"
38+
#include "UObject/UEPyUserDefinedStruct.h"
39+
#include "UObject/UEPyDataTable.h"
3840

3941

4042
#include "UEPyAssetUserData.h"
@@ -55,6 +57,12 @@
5557

5658
#include "Slate/UEPySlate.h"
5759

60+
#if ENGINE_MINOR_VERSION < 18
61+
#define USoftObjectProperty UAssetObjectProperty
62+
#define USoftClassProperty UAssetClassProperty
63+
typedef FAssetPtr FSoftObjectPtr;
64+
#endif
65+
5866
DEFINE_LOG_CATEGORY(LogPython);
5967

6068

@@ -260,6 +268,7 @@ static PyMethodDef unreal_engine_methods[] = {
260268

261269
{ "string_to_guid", py_unreal_engine_string_to_guid, METH_VARARGS, "" },
262270
{ "new_guid", py_unreal_engine_new_guid, METH_VARARGS, "" },
271+
{ "guid_to_string", py_unreal_engine_guid_to_string, METH_VARARGS, "" },
263272

264273
{ "heightmap_expand", py_unreal_engine_heightmap_expand, METH_VARARGS, "" },
265274
{ "heightmap_import", py_unreal_engine_heightmap_import, METH_VARARGS, "" },
@@ -480,6 +489,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
480489
{ "get_py_proxy", (PyCFunction)py_ue_get_py_proxy, METH_VARARGS, "" },
481490

482491
{ "post_edit_change", (PyCFunction)py_ue_post_edit_change, METH_VARARGS, "" },
492+
{ "post_edit_change_property", (PyCFunction)py_ue_post_edit_change_property, METH_VARARGS, "" },
483493
{ "pre_edit_change", (PyCFunction)py_ue_pre_edit_change, METH_VARARGS, "" },
484494
{ "modify", (PyCFunction)py_ue_modify, METH_VARARGS, "" },
485495

@@ -522,6 +532,20 @@ static PyMethodDef ue_PyUObject_methods[] = {
522532
{ "node_reconstruct", (PyCFunction)py_ue_node_reconstruct, METH_VARARGS, "" },
523533

524534
{ "get_material_graph", (PyCFunction)py_ue_get_material_graph, METH_VARARGS, "" },
535+
536+
{ "struct_add_variable", (PyCFunction)py_ue_struct_add_variable, METH_VARARGS, "" },
537+
{ "struct_get_variables", (PyCFunction)py_ue_struct_get_variables, METH_VARARGS, "" },
538+
{ "struct_remove_variable", (PyCFunction)py_ue_struct_remove_variable, METH_VARARGS, "" },
539+
{ "struct_move_variable_up", (PyCFunction)py_ue_struct_move_variable_up, METH_VARARGS, "" },
540+
{ "struct_move_variable_down", (PyCFunction)py_ue_struct_move_variable_down, METH_VARARGS, "" },
541+
542+
{ "data_table_add_row", (PyCFunction)py_ue_data_table_add_row, METH_VARARGS, "" },
543+
{ "data_table_remove_row", (PyCFunction)py_ue_data_table_remove_row, METH_VARARGS, "" },
544+
{ "data_table_rename_row", (PyCFunction)py_ue_data_table_rename_row, METH_VARARGS, "" },
545+
{ "data_table_as_dict", (PyCFunction)py_ue_data_table_as_dict, METH_VARARGS, "" },
546+
{ "data_table_as_json", (PyCFunction)py_ue_data_table_as_json, METH_VARARGS, "" },
547+
{ "data_table_find_row", (PyCFunction)py_ue_data_table_find_row, METH_VARARGS, "" },
548+
{ "data_table_get_all_rows", (PyCFunction)py_ue_data_table_get_all_rows, METH_VARARGS, "" },
525549
#endif
526550

527551
{ "is_rooted", (PyCFunction)py_ue_is_rooted, METH_VARARGS, "" },
@@ -691,7 +715,14 @@ static PyMethodDef ue_PyUObject_methods[] = {
691715
{ "get_current_level", (PyCFunction)py_ue_get_current_level, METH_VARARGS, "" },
692716
{ "set_current_level", (PyCFunction)py_ue_set_current_level, METH_VARARGS, "" },
693717

718+
#if WITH_EDITOR
719+
{ "add_foliage_asset", (PyCFunction)py_ue_add_foliage_asset, METH_VARARGS, "" },
720+
#endif
721+
{ "get_instanced_foliage_actor_for_current_level", (PyCFunction)py_ue_get_instanced_foliage_actor_for_current_level, METH_VARARGS, "" },
722+
723+
694724
{ "add_actor_component", (PyCFunction)py_ue_add_actor_component, METH_VARARGS, "" },
725+
{ "add_instance_component", (PyCFunction)py_ue_add_instance_component, METH_VARARGS, "" },
695726
{ "add_actor_root_component", (PyCFunction)py_ue_add_actor_root_component, METH_VARARGS, "" },
696727
{ "get_actor_component_by_type", (PyCFunction)py_ue_get_actor_component_by_type, METH_VARARGS, "" },
697728
{ "get_component_by_type", (PyCFunction)py_ue_get_actor_component_by_type, METH_VARARGS, "" },
@@ -937,7 +968,7 @@ void ue_pydelegates_cleanup(ue_PyUObject *self)
937968
#endif
938969
py_delegate->RemoveFromRoot();
939970
}
940-
}
971+
}
941972
self->python_delegates_gc->clear();
942973
delete self->python_delegates_gc;
943974
self->python_delegates_gc = nullptr;
@@ -1033,9 +1064,9 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
10331064
#else
10341065
return PyLong_FromLong(u_enum->FindEnumIndex(item.Key));
10351066
#endif
1067+
}
10361068
}
10371069
}
1038-
}
10391070
#endif
10401071
if (self->ue_object->IsA<UEnum>())
10411072
{
@@ -1047,16 +1078,16 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
10471078
return PyLong_FromLong(u_enum->FindEnumIndex(FName(UTF8_TO_TCHAR(attr))));
10481079
#endif
10491080
}
1050-
}
1081+
}
10511082

10521083
if (function)
10531084
{
10541085
// swallow previous exception
10551086
PyErr_Clear();
10561087
return py_ue_new_callable(function, self->ue_object);
10571088
}
1089+
}
10581090
}
1059-
}
10601091
return ret;
10611092
}
10621093

@@ -2049,7 +2080,7 @@ void unreal_engine_py_log_error()
20492080
if (zero)
20502081
{
20512082
msg = PyBytes_AsString(zero);
2052-
}
2083+
}
20532084
#else
20542085
msg = PyString_AsString(PyObject_Str(value));
20552086
#endif
@@ -2104,7 +2135,7 @@ void unreal_engine_py_log_error()
21042135
}
21052136

21062137
PyErr_Clear();
2107-
}
2138+
}
21082139

21092140
// retrieve a UWorld from a generic UObject (if possible)
21102141
UWorld *ue_get_uworld(ue_PyUObject *py_obj)
@@ -2235,8 +2266,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer)
22352266
Py_INCREF(ret);
22362267
return (PyObject *)ret;
22372268
}
2238-
Py_INCREF(Py_None);
2239-
return Py_None;
2269+
Py_RETURN_NONE;
22402270
}
22412271

22422272
if (auto casted_prop = Cast<UClassProperty>(prop))
@@ -2754,24 +2784,47 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer)
27542784
ue_PyUObject *ue_obj = (ue_PyUObject *)py_obj;
27552785
if (ue_obj->ue_object->IsA<UClass>())
27562786
{
2757-
auto casted_prop = Cast<UClassProperty>(prop);
2758-
if (!casted_prop)
2759-
return false;
2760-
casted_prop->SetPropertyValue_InContainer(buffer, (UClass *)ue_obj->ue_object);
2761-
return true;
2787+
if (auto casted_prop = Cast<UClassProperty>(prop))
2788+
{
2789+
casted_prop->SetPropertyValue_InContainer(buffer, ue_obj->ue_object);
2790+
return true;
2791+
}
2792+
else if (auto casted_prop_soft_class = Cast<USoftClassProperty>(prop))
2793+
{
2794+
casted_prop_soft_class->SetPropertyValue_InContainer(buffer, FSoftObjectPtr(ue_obj->ue_object));
2795+
return true;
2796+
}
2797+
else if (auto casted_prop_soft_object = Cast<USoftObjectProperty>(prop))
2798+
{
2799+
casted_prop_soft_object->SetPropertyValue_InContainer(buffer, FSoftObjectPtr(ue_obj->ue_object));
2800+
return true;
2801+
}
2802+
2803+
return false;
27622804
}
27632805

2806+
27642807
if (ue_obj->ue_object->IsA<UObject>())
27652808
{
2766-
auto casted_prop = Cast<UObjectPropertyBase>(prop);
2767-
if (!casted_prop)
2768-
return false;
2769-
// ensure the object type is correct, otherwise crash could happen (soon or later)
2770-
if (!ue_obj->ue_object->IsA(casted_prop->PropertyClass))
2771-
return false;
2772-
casted_prop->SetObjectPropertyValue_InContainer(buffer, ue_obj->ue_object);
2773-
return true;
2809+
if (auto casted_prop = Cast<UObjectPropertyBase>(prop))
2810+
{
2811+
// ensure the object type is correct, otherwise crash could happen (soon or later)
2812+
if (!ue_obj->ue_object->IsA(casted_prop->PropertyClass))
2813+
return false;
2814+
casted_prop->SetObjectPropertyValue_InContainer(buffer, ue_obj->ue_object);
2815+
return true;
2816+
}
2817+
else if (auto casted_prop_soft_object = Cast<USoftObjectProperty>(prop))
2818+
2819+
{
2820+
if (!ue_obj->ue_object->IsA(casted_prop_soft_object->PropertyClass))
2821+
return false;
2822+
casted_prop_soft_object->SetPropertyValue_InContainer(buffer, FSoftObjectPtr(ue_obj->ue_object));
2823+
return true;
2824+
}
2825+
27742826
}
2827+
return false;
27752828
}
27762829

27772830
if (py_obj == Py_None)
@@ -2979,9 +3032,9 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *
29793032
#else
29803033
prop->ImportText(*default_key_value, prop->ContainerPtrToValuePtr<uint8>(buffer), PPF_Localized, NULL);
29813034
#endif
2982-
}
3035+
}
29833036
#endif
2984-
}
3037+
}
29853038

29863039
Py_ssize_t tuple_len = PyTuple_Size(args);
29873040

@@ -3464,3 +3517,19 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_
34643517

34653518
return function;
34663519
}
3520+
3521+
FGuid *ue_py_check_fguid(PyObject *py_obj)
3522+
{
3523+
ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_obj);
3524+
if (!ue_py_struct)
3525+
{
3526+
return nullptr;
3527+
}
3528+
3529+
if (ue_py_struct->u_struct == FindObject<UScriptStruct>(ANY_PACKAGE, UTF8_TO_TCHAR((char *)"Guid")))
3530+
{
3531+
return (FGuid*)ue_py_struct->data;
3532+
}
3533+
3534+
return nullptr;
3535+
}

‎Source/UnrealEnginePython/Private/UEPyModule.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,5 @@ template <typename T> T *ue_py_check_struct(PyObject *py_obj) {
6969

7070
return nullptr;
7171
}
72+
73+
FGuid *ue_py_check_fguid(PyObject *);

0 commit comments

Comments
 (0)