Skip to content

Commit b4d5c3e

Browse files
author
Roberto De Ioris
committed
added archetype management
1 parent 8ca62b5 commit b4d5c3e

File tree

5 files changed

+100
-16
lines changed

5 files changed

+100
-16
lines changed

Source/UnrealEnginePython/Private/UEPyEditor.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,22 @@
3737
#include "Editor/MainFrame/Public/Interfaces/IMainFrameModule.h"
3838

3939
#include "Runtime/Core/Public/HAL/ThreadHeartBeat.h"
40+
#include "Runtime/Engine/Public/EditorSupportDelegates.h"
4041

4142
#include "UEPyIPlugin.h"
4243

44+
PyObject *py_unreal_engine_redraw_all_viewports(PyObject * self, PyObject * args)
45+
{
46+
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
47+
Py_RETURN_NONE;
48+
}
49+
50+
PyObject *py_unreal_engine_update_ui(PyObject * self, PyObject * args)
51+
{
52+
FEditorSupportDelegates::UpdateUI.Broadcast();
53+
Py_RETURN_NONE;
54+
}
55+
4356
PyObject *py_unreal_engine_editor_play_in_viewport(PyObject * self, PyObject * args)
4457
{
4558

@@ -273,7 +286,7 @@ PyObject *py_unreal_engine_editor_play(PyObject * self, PyObject * args)
273286
Py_END_ALLOW_THREADS;
274287

275288
Py_RETURN_NONE;
276-
}
289+
}
277290

278291
PyObject *py_unreal_engine_editor_select_actor(PyObject * self, PyObject * args)
279292
{
@@ -449,7 +462,7 @@ PyObject *py_unreal_engine_import_asset(PyObject * self, PyObject * args)
449462
}
450463

451464
Py_RETURN_NONE;
452-
}
465+
}
453466

454467
PyObject *py_unreal_engine_editor_tick(PyObject * self, PyObject * args)
455468
{
@@ -742,7 +755,7 @@ PyObject *py_unreal_engine_rename_asset(PyObject * self, PyObject * args)
742755
#endif
743756

744757
Py_RETURN_NONE;
745-
}
758+
}
746759

747760
PyObject *py_unreal_engine_duplicate_asset(PyObject * self, PyObject * args)
748761
{
@@ -1849,10 +1862,11 @@ PyObject *py_unreal_engine_on_main_frame_creation_finished(PyObject * self, PyOb
18491862
py_delegate->SetPyCallable(py_callable);
18501863
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
18511864
MainFrameModule.OnMainFrameCreationFinished().AddRaw(py_delegate, &FPythonSmartDelegate::PyFOnMainFrameCreationFinished);
1852-
1865+
18531866
Py_RETURN_NONE;
18541867
}
18551868

1869+
18561870
PyObject *py_unreal_engine_create_material_instance(PyObject * self, PyObject * args)
18571871
{
18581872

@@ -2060,7 +2074,7 @@ PyObject *py_unreal_engine_add_level_to_world(PyObject *self, PyObject * args)
20602074
#endif
20612075

20622076
Py_RETURN_UOBJECT(level_streaming);
2063-
}
2077+
}
20642078

20652079
PyObject *py_unreal_engine_move_selected_actors_to_level(PyObject *self, PyObject * args)
20662080
{

Source/UnrealEnginePython/Private/UEPyEditor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ PyObject *py_unreal_engine_get_assets_by_class(PyObject *, PyObject *);
2424
PyObject *py_unreal_engine_get_assets_by_filter(PyObject *, PyObject *, PyObject *);
2525
PyObject *py_unreal_engine_set_fbx_import_option(PyObject *, PyObject *);
2626

27+
PyObject *py_unreal_engine_redraw_all_viewports(PyObject *, PyObject *);
28+
PyObject *py_unreal_engine_update_ui(PyObject *, PyObject *);
29+
2730
PyObject *py_unreal_engine_create_modal_save_asset_dialog(PyObject *, PyObject *);
2831

2932
PyObject *py_unreal_engine_console_exec(PyObject *, PyObject * args);

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ static PyMethodDef unreal_engine_methods[] = {
304304

305305
{ "add_asset_view_context_menu_extension", py_unreal_engine_add_asset_view_context_menu_extension, METH_VARARGS, "" },
306306

307+
{ "redraw_all_viewports", py_unreal_engine_redraw_all_viewports, METH_VARARGS, "" },
308+
{ "update_ui", py_unreal_engine_update_ui, METH_VARARGS, "" },
309+
307310
#pragma warning(suppress: 4191)
308311
{ "create_detail_view", (PyCFunction)py_unreal_engine_create_detail_view, METH_VARARGS | METH_KEYWORDS, "" },
309312
#pragma warning(suppress: 4191)
@@ -463,7 +466,7 @@ static PyMethodDef unreal_engine_methods[] = {
463466
{ "get_viewport_size", py_unreal_engine_get_viewport_size, METH_VARARGS, "" },
464467
{ "get_resolution", py_unreal_engine_get_resolution, METH_VARARGS, "" },
465468
{ "get_game_viewport_size", py_unreal_engine_get_game_viewport_size, METH_VARARGS, "" },
466-
469+
467470
{ "get_game_viewport_client", py_unreal_engine_get_game_viewport_client, METH_VARARGS, "" },
468471
#pragma warning(suppress: 4191)
469472
{ "open_color_picker", (PyCFunction)py_unreal_engine_open_color_picker, METH_VARARGS | METH_KEYWORDS, "" },
@@ -1138,6 +1141,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
11381141
{ "as_dict", (PyCFunction)py_ue_as_dict, METH_VARARGS, "" },
11391142

11401143
{ "get_cdo", (PyCFunction)py_ue_get_cdo, METH_VARARGS, "" },
1144+
{ "get_archetype", (PyCFunction)py_ue_get_archetype, METH_VARARGS, "" },
1145+
{ "get_archetype_instances", (PyCFunction)py_ue_get_archetype_instances, METH_VARARGS, "" },
11411146
{ "enum_values", (PyCFunction)py_ue_enum_values, METH_VARARGS, "" },
11421147
{ "enum_names", (PyCFunction)py_ue_enum_names, METH_VARARGS, "" },
11431148
#if ENGINE_MINOR_VERSION >= 15
@@ -1295,8 +1300,35 @@ static int ue_PyUObject_setattro(ue_PyUObject *self, PyObject *attr_name, PyObje
12951300
UProperty *u_property = u_struct->FindPropertyByName(FName(UTF8_TO_TCHAR(attr)));
12961301
if (u_property)
12971302
{
1303+
#if WITH_EDITOR
1304+
self->ue_object->PreEditChange(u_property);
1305+
#endif
12981306
if (ue_py_convert_pyobject(value, u_property, (uint8*)self->ue_object, 0))
12991307
{
1308+
#if WITH_EDITOR
1309+
FPropertyChangedEvent PropertyEvent(u_property, EPropertyChangeType::ValueSet);
1310+
self->ue_object->PostEditChangeProperty(PropertyEvent);
1311+
1312+
if (self->ue_object->HasAnyFlags(RF_ArchetypeObject | RF_ClassDefaultObject))
1313+
{
1314+
TArray<UObject *> Instances;
1315+
self->ue_object->GetArchetypeInstances(Instances);
1316+
for (UObject *Instance : Instances)
1317+
{
1318+
Instance->PreEditChange(u_property);
1319+
if (ue_py_convert_pyobject(value, u_property, (uint8*)Instance, 0))
1320+
{
1321+
FPropertyChangedEvent PropertyEvent(u_property, EPropertyChangeType::ValueSet);
1322+
Instance->PostEditChangeProperty(PropertyEvent);
1323+
}
1324+
else
1325+
{
1326+
PyErr_SetString(PyExc_ValueError, "invalid value for UProperty");
1327+
return -1;
1328+
}
1329+
}
1330+
}
1331+
#endif
13001332
return 0;
13011333
}
13021334
PyErr_SetString(PyExc_ValueError, "invalid value for UProperty");
@@ -1726,7 +1758,9 @@ void unreal_engine_init_py_module()
17261758
PyDict_SetItemString(unreal_engine_dict, "RF_MARKASNATIVE", PyLong_FromUnsignedLongLong((uint64)RF_MarkAsNative));
17271759
PyDict_SetItemString(unreal_engine_dict, "RF_TRANSACTIONAL", PyLong_FromUnsignedLongLong((uint64)RF_Transactional));
17281760
PyDict_SetItemString(unreal_engine_dict, "RF_CLASSDEFAULTOBJECT", PyLong_FromUnsignedLongLong((uint64)RF_ClassDefaultObject));
1761+
PyDict_SetItemString(unreal_engine_dict, "RF_CLASS_DEFAULT_OBJECT", PyLong_FromUnsignedLongLong((uint64)RF_ClassDefaultObject));
17291762
PyDict_SetItemString(unreal_engine_dict, "RF_ARCHETYPEOBJECT", PyLong_FromUnsignedLongLong((uint64)RF_ArchetypeObject));
1763+
PyDict_SetItemString(unreal_engine_dict, "RF_ARCHETYPE_OBJECT", PyLong_FromUnsignedLongLong((uint64)RF_ArchetypeObject));
17301764
PyDict_SetItemString(unreal_engine_dict, "RF_TRANSIENT", PyLong_FromUnsignedLongLong((uint64)RF_Transient));
17311765
PyDict_SetItemString(unreal_engine_dict, "RF_MARKASROOTSET", PyLong_FromUnsignedLongLong((uint64)RF_MarkAsRootSet));
17321766
PyDict_SetItemString(unreal_engine_dict, "RF_TAGGARBAGETEMP", PyLong_FromUnsignedLongLong((uint64)RF_TagGarbageTemp));
@@ -1814,10 +1848,10 @@ ue_PyUObject *ue_get_python_uobject(UObject *ue_obj)
18141848
UE_LOG(LogPython, Warning, TEXT("CREATED UPyObject at %p for %p %s"), ue_py_object, ue_obj, *ue_obj->GetName());
18151849
#endif
18161850
return ue_py_object;
1817-
}
1851+
}
18181852
return ret;
18191853

1820-
}
1854+
}
18211855

18221856
ue_PyUObject *ue_get_python_uobject_inc(UObject *ue_obj)
18231857
{
@@ -1905,7 +1939,7 @@ void unreal_engine_py_log_error()
19051939
}
19061940

19071941
PyErr_Clear();
1908-
}
1942+
}
19091943

19101944
// retrieve a UWorld from a generic UObject (if possible)
19111945
UWorld *ue_get_uworld(ue_PyUObject *py_obj)
@@ -2841,8 +2875,8 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *
28412875
#endif
28422876
}
28432877
#endif
2878+
}
28442879
}
2845-
}
28462880

28472881

28482882
Py_ssize_t tuple_len = PyTuple_Size(args);
@@ -2955,7 +2989,7 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *
29552989
return ret;
29562990

29572991
Py_RETURN_NONE;
2958-
}
2992+
}
29592993

29602994
PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_callable, bool fail_on_wrong_property)
29612995
{
@@ -3015,8 +3049,8 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_
30153049
{
30163050
UE_LOG(LogPython, Error, TEXT("function %s is already registered"), UTF8_TO_TCHAR(name));
30173051
return nullptr;
3018-
}
30193052
}
3053+
}
30203054

30213055
UPythonFunction *function = NewObject<UPythonFunction>(u_class, UTF8_TO_TCHAR(name), RF_Public | RF_Transient | RF_MarkAsNative);
30223056
function->SetPyCallable(py_callable);
@@ -3337,7 +3371,7 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_
33373371
#endif
33383372

33393373
return function;
3340-
}
3374+
}
33413375

33423376
FGuid *ue_py_check_fguid(PyObject *py_obj)
33433377
{

Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,16 +1894,47 @@ PyObject *py_ue_get_cdo(ue_PyUObject * self, PyObject * args)
18941894

18951895
ue_py_check(self);
18961896

1897-
if (!self->ue_object->IsA<UClass>())
1897+
UClass *u_class = ue_py_check_type<UClass>(self);
1898+
if (!u_class)
18981899
{
18991900
return PyErr_Format(PyExc_Exception, "uobject is not a UClass");
19001901
}
19011902

1902-
UClass *u_class = (UClass *)self->ue_object;
1903-
19041903
Py_RETURN_UOBJECT(u_class->GetDefaultObject());
19051904
}
19061905

1906+
PyObject *py_ue_get_archetype(ue_PyUObject * self, PyObject * args)
1907+
{
1908+
1909+
ue_py_check(self);
1910+
1911+
UObject *Archetype = self->ue_object->GetArchetype();
1912+
1913+
if (!Archetype)
1914+
return PyErr_Format(PyExc_Exception, "uobject has no archetype");
1915+
1916+
Py_RETURN_UOBJECT(Archetype);
1917+
}
1918+
1919+
PyObject *py_ue_get_archetype_instances(ue_PyUObject * self, PyObject * args)
1920+
{
1921+
1922+
ue_py_check(self);
1923+
1924+
TArray<UObject *> Instances;
1925+
1926+
self->ue_object->GetArchetypeInstances(Instances);
1927+
1928+
PyObject *py_list = PyList_New(0);
1929+
1930+
for (UObject *Instance : Instances)
1931+
{
1932+
PyList_Append(py_list, (PyObject *)ue_get_python_uobject(Instance));
1933+
}
1934+
1935+
return py_list;
1936+
}
1937+
19071938

19081939
#if WITH_EDITOR
19091940
PyObject *py_ue_save_package(ue_PyUObject * self, PyObject * args)

Source/UnrealEnginePython/Private/UObject/UEPyObject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ PyObject *py_ue_is_owned(ue_PyUObject *, PyObject *);
4141
PyObject *py_ue_save_config(ue_PyUObject *, PyObject *);
4242

4343
PyObject *py_ue_get_cdo(ue_PyUObject *, PyObject *);
44+
PyObject *py_ue_get_archetype(ue_PyUObject *, PyObject *);
45+
PyObject *py_ue_get_archetype_instances(ue_PyUObject *, PyObject *);
4446
PyObject *py_ue_enum_values(ue_PyUObject *, PyObject *);
4547
PyObject *py_ue_enum_names(ue_PyUObject *, PyObject *);
4648
#if ENGINE_MINOR_VERSION >= 15

0 commit comments

Comments
 (0)