From b9fb9291d68612a02789cc552da50c93e011747b Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Sun, 13 Jan 2019 10:24:05 +0100 Subject: [PATCH 01/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1885cd358..46264da12 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole' All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell) -The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19 and 4.20 +The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20 and 4.21 We support official python.org releases as well as IntelPython and Anaconda distributions. From dc6e93cd2a87a0d77e03c3a9d423f2a32c2f776d Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 18 Feb 2019 21:55:08 -0700 Subject: [PATCH 02/23] added support for uobj.unbind_event --- .../Private/PythonDelegate.cpp | 9 ++++- .../UnrealEnginePython/Private/UEPyModule.cpp | 40 +++++++++++++++++++ .../UnrealEnginePython/Private/UEPyModule.h | 1 + .../Private/UObject/UEPyObject.cpp | 19 +++++++++ .../Private/UObject/UEPyObject.h | 3 +- .../Public/PythonDelegate.h | 1 + .../Public/PythonHouseKeeper.h | 11 +++++ 7 files changed, 82 insertions(+), 2 deletions(-) diff --git a/Source/UnrealEnginePython/Private/PythonDelegate.cpp b/Source/UnrealEnginePython/Private/PythonDelegate.cpp index 0ed596d4b..e7e4c6699 100644 --- a/Source/UnrealEnginePython/Private/PythonDelegate.cpp +++ b/Source/UnrealEnginePython/Private/PythonDelegate.cpp @@ -1,6 +1,7 @@ #include "PythonDelegate.h" #include "UEPyModule.h" +#include "UEPyCallable.h" UPythonDelegate::UPythonDelegate() { @@ -101,6 +102,12 @@ void UPythonDelegate::PyInputAxisHandler(float value) Py_DECREF(ret); } +bool UPythonDelegate::UsesPyCallable(PyObject *other) +{ + ue_PyCallable *other_callable = (ue_PyCallable*)other; + ue_PyCallable *this_callable = (ue_PyCallable*)py_callable; + return other_callable->u_function == this_callable->u_function && other_callable->u_target == this_callable->u_target; +} UPythonDelegate::~UPythonDelegate() { @@ -110,4 +117,4 @@ UPythonDelegate::~UPythonDelegate() #if defined(UEPY_MEMORY_DEBUG) UE_LOG(LogPython, Warning, TEXT("PythonDelegate %p callable XDECREF'ed"), this); #endif -} \ No newline at end of file +} diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index 704593c8d..993828a86 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -607,6 +607,7 @@ static PyMethodDef ue_PyUObject_methods[] = { { "set_name", (PyCFunction)py_ue_set_name, METH_VARARGS, "" }, { "bind_event", (PyCFunction)py_ue_bind_event, METH_VARARGS, "" }, + { "unbind_event", (PyCFunction)py_ue_unbind_event, METH_VARARGS, "" }, { "delegate_bind_ufunction", (PyCFunction)py_ue_delegate_bind_ufunction, METH_VARARGS, "" }, { "get_py_proxy", (PyCFunction)py_ue_get_py_proxy, METH_VARARGS, "" }, @@ -3044,6 +3045,45 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * Py_RETURN_NONE; } +PyObject *ue_unbind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_callable, bool fail_on_wrong_property) +{ + UProperty *u_property = u_obj->ue_object->GetClass()->FindPropertyByName(FName(*event_name)); + if (!u_property) + { + if (fail_on_wrong_property) + return PyErr_Format(PyExc_Exception, "unable to find event property %s", TCHAR_TO_UTF8(*event_name)); + Py_RETURN_NONE; + } + + if (auto casted_prop = Cast(u_property)) + { + UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->FindDelegate(u_obj->ue_object, py_callable); + if (py_delegate != nullptr) + { + FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object); + multiscript_delegate.Remove(py_delegate, FName("PyFakeCallable")); + + // re-assign multicast delegate + casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, multiscript_delegate); + } + } + else if (auto casted_prop_delegate = Cast(u_property)) + { + FScriptDelegate script_delegate = casted_prop_delegate->GetPropertyValue_InContainer(u_obj->ue_object); + script_delegate.Unbind(); + + // re-assign multicast delegate + casted_prop_delegate->SetPropertyValue_InContainer(u_obj->ue_object, script_delegate); + } + else + { + if (fail_on_wrong_property) + return PyErr_Format(PyExc_Exception, "property %s is not an event", TCHAR_TO_UTF8(*event_name)); + } + + Py_RETURN_NONE; +} + PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_callable, bool fail_on_wrong_property) { diff --git a/Source/UnrealEnginePython/Private/UEPyModule.h b/Source/UnrealEnginePython/Private/UEPyModule.h index 08e599d52..9d865cb16 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.h +++ b/Source/UnrealEnginePython/Private/UEPyModule.h @@ -35,6 +35,7 @@ void ue_bind_events_for_py_class_by_attribute(UObject *, PyObject *); void ue_autobind_events_for_pyclass(ue_PyUObject *, PyObject *); PyObject *ue_bind_pyevent(ue_PyUObject *, FString, PyObject *, bool); +PyObject *ue_unbind_pyevent(ue_PyUObject *, FString, PyObject *, bool); PyObject *py_ue_ufunction_call(UFunction *, UObject *, PyObject *, int, PyObject *); diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp index e7fcb7de5..d11031775 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp @@ -1517,6 +1517,25 @@ PyObject *py_ue_bind_event(ue_PyUObject * self, PyObject * args) return ue_bind_pyevent(self, FString(event_name), py_callable, true); } +PyObject *py_ue_unbind_event(ue_PyUObject * self, PyObject * args) +{ + ue_py_check(self); + + char *event_name; + PyObject *py_callable; + if (!PyArg_ParseTuple(args, "sO:bind_event", &event_name, &py_callable)) + { + return NULL; + } + + if (!PyCallable_Check(py_callable)) + { + return PyErr_Format(PyExc_Exception, "object is not callable"); + } + + return ue_unbind_pyevent(self, FString(event_name), py_callable, true); +} + PyObject *py_ue_delegate_bind_ufunction(ue_PyUObject * self, PyObject * args) { ue_py_check(self); diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyObject.h b/Source/UnrealEnginePython/Private/UObject/UEPyObject.h index 4f66b78f7..6fb4678fe 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyObject.h +++ b/Source/UnrealEnginePython/Private/UObject/UEPyObject.h @@ -51,6 +51,7 @@ PyObject *py_ue_enum_user_defined_names(ue_PyUObject *, PyObject *); PyObject *py_ue_bind_event(ue_PyUObject *, PyObject *); +PyObject *py_ue_unbind_event(ue_PyUObject *, PyObject *); PyObject *py_ue_add_function(ue_PyUObject *, PyObject *); PyObject *py_ue_add_property(ue_PyUObject *, PyObject *); @@ -111,4 +112,4 @@ PyObject *py_ue_render_thumbnail(ue_PyUObject *, PyObject *); PyObject *py_ue_to_bytes(ue_PyUObject *, PyObject *); PyObject *py_ue_to_bytearray(ue_PyUObject *, PyObject *); -PyObject *py_ue_from_bytes(ue_PyUObject *, PyObject *); \ No newline at end of file +PyObject *py_ue_from_bytes(ue_PyUObject *, PyObject *); diff --git a/Source/UnrealEnginePython/Public/PythonDelegate.h b/Source/UnrealEnginePython/Public/PythonDelegate.h index 01d0f70b7..be46aa511 100644 --- a/Source/UnrealEnginePython/Public/PythonDelegate.h +++ b/Source/UnrealEnginePython/Public/PythonDelegate.h @@ -13,6 +13,7 @@ class UPythonDelegate : public UObject ~UPythonDelegate(); virtual void ProcessEvent(UFunction *function, void *Parms) override; void SetPyCallable(PyObject *callable); + bool UsesPyCallable(PyObject *callable); void SetSignature(UFunction *original_signature); void PyInputHandler(); diff --git a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h index ed36ecc63..dcde4d3a7 100644 --- a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h +++ b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h @@ -238,6 +238,17 @@ class FUnrealEnginePythonHouseKeeper : public FGCObject return Garbaged; } + UPythonDelegate *FindDelegate(UObject *Owner, PyObject *PyCallable) + { + for (int32 i = PyDelegatesTracker.Num() - 1; i >= 0; --i) + { + FPythonDelegateTracker &Tracker = PyDelegatesTracker[i]; + if (Tracker.Owner.Get() == Owner && Tracker.Delegate->UsesPyCallable(PyCallable)) + return Tracker.Delegate; + } + return nullptr; + } + UPythonDelegate *NewDelegate(UObject *Owner, PyObject *PyCallable, UFunction *Signature) { UPythonDelegate *Delegate = NewObject(); From 30e723241336db7241f4215d50773803161ce6f3 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Thu, 7 Mar 2019 08:07:02 +0100 Subject: [PATCH 03/23] preliminary support for 4.22 --- .../Private/Slate/UEPySImage.h | 4 ++++ .../UnrealEnginePython/Private/UEPyEditor.cpp | 17 +++++++++++++---- .../Private/UObject/UEPyLandscape.cpp | 4 ++++ .../UnrealEnginePython.Build.cs | 2 -- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Source/UnrealEnginePython/Private/Slate/UEPySImage.h b/Source/UnrealEnginePython/Private/Slate/UEPySImage.h index fb608ef55..584e14e50 100644 --- a/Source/UnrealEnginePython/Private/Slate/UEPySImage.h +++ b/Source/UnrealEnginePython/Private/Slate/UEPySImage.h @@ -5,7 +5,11 @@ #include "UEPySLeafWidget.h" +#if ENGINE_MINOR_VERSION > 21 +#include "Runtime/SlateCore/Public/Widgets/Images/SImage.h" +#else #include "Runtime/Slate/Public/Widgets/Images/SImage.h" +#endif #include "Runtime/SlateCore/Public/Styling/SlateBrush.h" extern PyTypeObject ue_PySImageType; diff --git a/Source/UnrealEnginePython/Private/UEPyEditor.cpp b/Source/UnrealEnginePython/Private/UEPyEditor.cpp index 4d117dff4..e994cf121 100644 --- a/Source/UnrealEnginePython/Private/UEPyEditor.cpp +++ b/Source/UnrealEnginePython/Private/UEPyEditor.cpp @@ -286,7 +286,7 @@ PyObject *py_unreal_engine_editor_play(PyObject * self, PyObject * args) Py_END_ALLOW_THREADS; Py_RETURN_NONE; - } +} PyObject *py_unreal_engine_editor_select_actor(PyObject * self, PyObject * args) { @@ -462,7 +462,7 @@ PyObject *py_unreal_engine_import_asset(PyObject * self, PyObject * args) } Py_RETURN_NONE; - } +} PyObject *py_unreal_engine_editor_tick(PyObject * self, PyObject * args) { @@ -796,7 +796,7 @@ PyObject *py_unreal_engine_rename_asset(PyObject * self, PyObject * args) #endif Py_RETURN_NONE; - } +} PyObject *py_unreal_engine_duplicate_asset(PyObject * self, PyObject * args) { @@ -1879,7 +1879,11 @@ PyObject *py_unreal_engine_editor_on_asset_post_import(PyObject * self, PyObject return PyErr_Format(PyExc_Exception, "object is not a callable"); TSharedRef py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewPythonSmartDelegate(py_callable); +#if ENGINE_MINOR_VERSION > 21 + GEditor->GetEditorSubsystem()->OnAssetPostImport.AddSP(py_delegate, &FPythonSmartDelegate::PyFOnAssetPostImport); +#else FEditorDelegates::OnAssetPostImport.AddSP(py_delegate, &FPythonSmartDelegate::PyFOnAssetPostImport); +#endif Py_RETURN_NONE; } @@ -2115,7 +2119,7 @@ PyObject *py_unreal_engine_add_level_to_world(PyObject *self, PyObject * args) #endif Py_RETURN_UOBJECT(level_streaming); - } +} PyObject *py_unreal_engine_move_selected_actors_to_level(PyObject *self, PyObject * args) { @@ -2533,7 +2537,11 @@ PyObject *py_unreal_engine_unregister_settings(PyObject * self, PyObject * args) PyObject *py_unreal_engine_all_viewport_clients(PyObject * self, PyObject * args) { +#if ENGINE_MINOR_VERSION > 21 + TArray clients = GEditor->GetAllViewportClients(); +#else TArray clients = GEditor->AllViewportClients; +#endif PyObject *py_list = PyList_New(0); for (FEditorViewportClient *client : clients) { @@ -2647,5 +2655,6 @@ PyObject *py_unreal_engine_export_assets(PyObject * self, PyObject * args) Py_RETURN_NONE; } + #endif diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp index 883a6ba0f..fbd27d2df 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp @@ -85,10 +85,14 @@ PyObject *py_ue_landscape_export_to_raw_mesh(ue_PyUObject *self, PyObject * args if (!landscape) return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy"); +#if ENGINE_MINOR_VERSION > 21 + return PyErr_Format(PyExc_Exception, "MeshDescription struct is still unsupported");; +#else FRawMesh raw_mesh; if (!landscape->ExportToRawMesh(lod, raw_mesh)) return PyErr_Format(PyExc_Exception, "unable to export landscape to FRawMesh"); return py_ue_new_fraw_mesh(raw_mesh); +#endif } #endif diff --git a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs index 96b48121d..51394b033 100644 --- a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs +++ b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs @@ -100,7 +100,6 @@ public UnrealEnginePython(TargetInfo Target) PublicIncludePaths.AddRange( new string[] { - "UnrealEnginePython/Public", // ... add public include paths required here ... } ); @@ -108,7 +107,6 @@ public UnrealEnginePython(TargetInfo Target) PrivateIncludePaths.AddRange( new string[] { - "UnrealEnginePython/Private", // ... add other private include paths required here ... } ); From e2802a5cdf361a0dfa74c63e6ce1d645ae431612 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Thu, 7 Mar 2019 08:23:34 +0100 Subject: [PATCH 04/23] use FRichCurve instead of FInterpCurveFloat in Sequencer api --- .../Private/UObject/UEPySequencer.cpp | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/Source/UnrealEnginePython/Private/UObject/UEPySequencer.cpp b/Source/UnrealEnginePython/Private/UObject/UEPySequencer.cpp index 7d506be0e..8858a7936 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPySequencer.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPySequencer.cpp @@ -68,6 +68,51 @@ static bool magic_get_frame_number(UMovieScene *MovieScene, PyObject *py_obj, FF } #if WITH_EDITOR +#if ENGINE_MINOR_VERSION > 21 +static void ImportTransformChannel(const FRichCurve& Source, FMovieSceneFloatChannel* Dest, FFrameRate DestFrameRate, bool bNegateTangents) +{ + TMovieSceneChannelData ChannelData = Dest->GetData(); + ChannelData.Reset(); + double DecimalRate = DestFrameRate.AsDecimal(); + for (int32 KeyIndex = 0; KeyIndex < Source.Keys.Num(); ++KeyIndex) + { + float ArriveTangent = Source.Keys[KeyIndex].ArriveTangent; + if (KeyIndex > 0) + { + ArriveTangent = ArriveTangent / ((Source.Keys[KeyIndex].Value - Source.Keys[KeyIndex - 1].Value) * DecimalRate); + } + + float LeaveTangent = Source.Keys[KeyIndex].LeaveTangent; + if (KeyIndex < Source.Keys.Num() - 1) + { + LeaveTangent = LeaveTangent / ((Source.Keys[KeyIndex + 1].Value - Source.Keys[KeyIndex].Value) * DecimalRate); + } + + if (bNegateTangents) + { + ArriveTangent = -ArriveTangent; + LeaveTangent = -LeaveTangent; + } + + FFrameNumber KeyTime = (Source.Keys[KeyIndex].Value * DestFrameRate).RoundToFrame(); + if (ChannelData.FindKey(KeyTime) == INDEX_NONE) + { + FMovieSceneFloatValue NewKey(Source.Keys[KeyIndex].Value); + + NewKey.InterpMode = Source.Keys[KeyIndex].InterpMode; + NewKey.TangentMode = Source.Keys[KeyIndex].TangentMode; + NewKey.Tangent.ArriveTangent = ArriveTangent / DestFrameRate.AsDecimal(); + NewKey.Tangent.LeaveTangent = LeaveTangent / DestFrameRate.AsDecimal(); + NewKey.Tangent.TangentWeightMode = RCTWM_WeightedNone; + NewKey.Tangent.ArriveTangentWeight = 0.0f; + NewKey.Tangent.LeaveTangentWeight = 0.0f; + ChannelData.AddKey(KeyTime, NewKey); + } + } + + Dest->AutoSetTangents(); +} +#else static void ImportTransformChannel(const FInterpCurveFloat& Source, FMovieSceneFloatChannel* Dest, FFrameRate DestFrameRate, bool bNegateTangents) { TMovieSceneChannelData ChannelData = Dest->GetData(); @@ -103,18 +148,27 @@ static void ImportTransformChannel(const FInterpCurveFloat& Source, FMovieSceneF Dest->AutoSetTangents(); } +#endif static bool ImportFBXTransform(FString NodeName, UMovieScene3DTransformSection* TransformSection, UnFbx::FFbxCurvesAPI& CurveAPI) { // Look for transforms explicitly + FTransform DefaultTransform; + +#if ENGINE_MINOR_VERSION > 21 + FRichCurve Translation[3]; + FRichCurve EulerRotation[3]; + FRichCurve Scale[3]; +#else FInterpCurveFloat Translation[3]; FInterpCurveFloat EulerRotation[3]; FInterpCurveFloat Scale[3]; - FTransform DefaultTransform; +#endif CurveAPI.GetConvertedTransformCurveData(NodeName, Translation[0], Translation[1], Translation[2], EulerRotation[0], EulerRotation[1], EulerRotation[2], Scale[0], Scale[1], Scale[2], DefaultTransform); + TransformSection->Modify(); FFrameRate FrameRate = TransformSection->GetTypedOuter()->GetTickResolution(); @@ -1594,9 +1648,15 @@ PyObject *py_ue_sequencer_import_fbx_transform(ue_PyUObject *self, PyObject * ar continue; // Look for transforms explicitly +#if ENGINE_MINOR_VERSION > 21 + FRichCurve Translation[3]; + FRichCurve EulerRotation[3]; + FRichCurve Scale[3]; +#else FInterpCurveFloat Translation[3]; FInterpCurveFloat EulerRotation[3]; FInterpCurveFloat Scale[3]; +#endif FTransform DefaultTransform; #if ENGINE_MINOR_VERSION >= 18 CurveAPI.GetConvertedTransformCurveData(NodeName, Translation[0], Translation[1], Translation[2], EulerRotation[0], EulerRotation[1], EulerRotation[2], Scale[0], Scale[1], Scale[2], DefaultTransform); From 020763ac04138323abf99b0d09fc600f0762bbd9 Mon Sep 17 00:00:00 2001 From: Devin Curry Date: Tue, 12 Mar 2019 10:46:02 -0700 Subject: [PATCH 05/23] Add break_all_links() and get_linked_to() for blueprint pins --- .../Private/Blueprint/UEPyEdGraphPin.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraphPin.cpp b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraphPin.cpp index dca7bf864..283079f31 100644 --- a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraphPin.cpp +++ b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraphPin.cpp @@ -80,9 +80,49 @@ static PyObject *py_ue_edgraphpin_break_link_to(ue_PyEdGraphPin *self, PyObject Py_RETURN_NONE; } +static PyObject *py_ue_edgraphpin_break_all_pin_links(ue_PyEdGraphPin *self, PyObject * args) +{ + PyObject *py_notify_nodes = nullptr; + if (!PyArg_ParseTuple(args, "O:break_all_pin_links", &py_notify_nodes)) + { + return NULL; + } + + bool notify_nodes = true; + if (py_notify_nodes && !PyObject_IsTrue(py_notify_nodes)) + notify_nodes = false; + + self->pin->BreakAllPinLinks(notify_nodes); + + if (UBlueprint *bp = Cast(self->pin->GetOwningNode()->GetGraph()->GetOuter())) + { + FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp); + } + + Py_RETURN_NONE; +} + +static PyObject *py_ue_edgraphpin_get_linked_to(ue_PyEdGraphPin * self, PyObject * args) +{ + PyObject *pins = PyList_New(0); + + TArray Links = self->pin->LinkedTo; + + for (int32 i = 0; i < Links.Num(); i++) + { + UEdGraphPin *pin = Links[i]; + ue_PyUObject *item = (ue_PyUObject *)py_ue_new_edgraphpin(pin); + if (item) + PyList_Append(pins, (PyObject *)item); + } + return pins; +} + static PyMethodDef ue_PyEdGraphPin_methods[] = { { "make_link_to", (PyCFunction)py_ue_edgraphpin_make_link_to, METH_VARARGS, "" }, { "break_link_to", (PyCFunction)py_ue_edgraphpin_break_link_to, METH_VARARGS, "" }, + { "break_all_pin_links", (PyCFunction)py_ue_edgraphpin_break_all_pin_links, METH_VARARGS, "" }, + { "get_linked_to", (PyCFunction)py_ue_edgraphpin_get_linked_to, METH_VARARGS, "" }, { "connect", (PyCFunction)py_ue_edgraphpin_connect, METH_VARARGS, "" }, { NULL } /* Sentinel */ }; From 1da9fbc7002c2f1c33762cf97064b09faf85bcb1 Mon Sep 17 00:00:00 2001 From: dave Date: Wed, 13 Mar 2019 17:11:14 -0600 Subject: [PATCH 06/23] fixed 4.19 build --- Source/UnrealEnginePython/UnrealEnginePython.Build.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs index 51394b033..48d6618c1 100644 --- a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs +++ b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs @@ -107,6 +107,9 @@ public UnrealEnginePython(TargetInfo Target) PrivateIncludePaths.AddRange( new string[] { +#if !UE_4_22_OR_LATER + "UnrealEnginePython/Private", +#endif // ... add other private include paths required here ... } ); From 8ed4abccdc503f91154ff8bd791e464292319a47 Mon Sep 17 00:00:00 2001 From: dave Date: Thu, 14 Mar 2019 10:05:50 -0600 Subject: [PATCH 07/23] Split PythonHouseKeeper into .h and .cpp file for easier debugging --- .../Private/PythonHouseKeeper.cpp | 255 +++++++++++++ .../Public/PythonHouseKeeper.h | 340 +++--------------- .../UnrealEnginePython.Build.cs | 3 - 3 files changed, 309 insertions(+), 289 deletions(-) create mode 100644 Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp diff --git a/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp b/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp new file mode 100644 index 000000000..ea9d5dda3 --- /dev/null +++ b/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp @@ -0,0 +1,255 @@ +#pragma once + +#include "PythonHouseKeeper.h" + +void FUnrealEnginePythonHouseKeeper::AddReferencedObjects(FReferenceCollector& InCollector) +{ + InCollector.AddReferencedObjects(PythonTrackedObjects); +} + +FUnrealEnginePythonHouseKeeper *FUnrealEnginePythonHouseKeeper::Get() +{ + static FUnrealEnginePythonHouseKeeper *Singleton; + if (!Singleton) + { + Singleton = new FUnrealEnginePythonHouseKeeper(); + // register a new delegate for the GC +#if ENGINE_MINOR_VERSION >= 18 + FCoreUObjectDelegates::GetPostGarbageCollect().AddRaw(Singleton, &FUnrealEnginePythonHouseKeeper::RunGCDelegate); +#else + FCoreUObjectDelegates::PostGarbageCollect.AddRaw(Singleton, &FUnrealEnginePythonHouseKeeper::RunGCDelegate); +#endif + } + return Singleton; +} + +void FUnrealEnginePythonHouseKeeper::RunGCDelegate() +{ + FScopePythonGIL gil; + RunGC(); +} + +int32 FUnrealEnginePythonHouseKeeper::RunGC() +{ + int32 Garbaged = PyUObjectsGC(); + Garbaged += DelegatesGC(); + return Garbaged; +} + +bool FUnrealEnginePythonHouseKeeper::IsValidPyUObject(ue_PyUObject *PyUObject) +{ + if (!PyUObject) + return false; + + UObject *Object = PyUObject->ue_object; + FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); + if (!Tracker) + { + return false; + } + + if (!Tracker->Owner.IsValid()) + return false; + + return true; + +} + +void FUnrealEnginePythonHouseKeeper::TrackUObject(UObject *Object) +{ + FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); + if (!Tracker) + { + return; + } + if (Tracker->bPythonOwned) + return; + Tracker->bPythonOwned = true; + // when a new ue_PyUObject spawns, it has a reference counting of two + Py_DECREF(Tracker->PyUObject); + Tracker->PyUObject->owned = 1; + PythonTrackedObjects.Add(Object); +} + +void FUnrealEnginePythonHouseKeeper::UntrackUObject(UObject *Object) +{ + PythonTrackedObjects.Remove(Object); +} + +void FUnrealEnginePythonHouseKeeper::RegisterPyUObject(UObject *Object, ue_PyUObject *InPyUObject) +{ + UObjectPyMapping.Add(Object, FPythonUOjectTracker(Object, InPyUObject)); +} + +void FUnrealEnginePythonHouseKeeper::UnregisterPyUObject(UObject *Object) +{ + UObjectPyMapping.Remove(Object); +} + +ue_PyUObject *FUnrealEnginePythonHouseKeeper::GetPyUObject(UObject *Object) +{ + FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); + if (!Tracker) + { + return nullptr; + } + + if (!Tracker->Owner.IsValid(true)) + { +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Warning, TEXT("DEFREF'ing UObject at %p (refcnt: %d)"), Object, Tracker->PyUObject->ob_base.ob_refcnt); +#endif + if (!Tracker->bPythonOwned) + Py_DECREF((PyObject *)Tracker->PyUObject); + UnregisterPyUObject(Object); + return nullptr; +} + + return Tracker->PyUObject; +} + +uint32 FUnrealEnginePythonHouseKeeper::PyUObjectsGC() +{ + uint32 Garbaged = 0; + TArray BrokenList; + for (auto &UObjectPyItem : UObjectPyMapping) + { + UObject *Object = UObjectPyItem.Key; + FPythonUOjectTracker &Tracker = UObjectPyItem.Value; +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Warning, TEXT("Checking for UObject at %p"), Object); +#endif + if (!Tracker.Owner.IsValid(true)) + { +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Warning, TEXT("Removing UObject at %p (refcnt: %d)"), Object, Tracker.PyUObject->ob_base.ob_refcnt); +#endif + BrokenList.Add(Object); + Garbaged++; + } + else + { +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Error, TEXT("UObject at %p %s is in use"), Object, *Object->GetName()); +#endif +} + } + + for (UObject *Object : BrokenList) + { + FPythonUOjectTracker &Tracker = UObjectPyMapping[Object]; + if (!Tracker.bPythonOwned) + Py_DECREF((PyObject *)Tracker.PyUObject); + UnregisterPyUObject(Object); + } + + return Garbaged; + +} + + +int32 FUnrealEnginePythonHouseKeeper::DelegatesGC() +{ + int32 Garbaged = 0; +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Display, TEXT("Garbage collecting %d UObject delegates"), PyDelegatesTracker.Num()); +#endif + for (int32 i = PyDelegatesTracker.Num() - 1; i >= 0; --i) + { + FPythonDelegateTracker &Tracker = PyDelegatesTracker[i]; + if (!Tracker.Owner.IsValid(true)) + { + Tracker.Delegate->RemoveFromRoot(); + PyDelegatesTracker.RemoveAt(i); + Garbaged++; + } + + } + +#if defined(UEPY_MEMORY_DEBUG) + UE_LOG(LogPython, Display, TEXT("Garbage collecting %d Slate delegates"), PySlateDelegatesTracker.Num()); +#endif + + for (int32 i = PySlateDelegatesTracker.Num() - 1; i >= 0; --i) + { + FPythonSWidgetDelegateTracker &Tracker = PySlateDelegatesTracker[i]; + if (!Tracker.Owner.IsValid()) + { + PySlateDelegatesTracker.RemoveAt(i); + Garbaged++; + } + + } + return Garbaged; + } + +UPythonDelegate *FUnrealEnginePythonHouseKeeper::FindDelegate(UObject *Owner, PyObject *PyCallable) +{ + for (int32 i = PyDelegatesTracker.Num() - 1; i >= 0; --i) + { + FPythonDelegateTracker &Tracker = PyDelegatesTracker[i]; + if (Tracker.Owner.Get() == Owner && Tracker.Delegate->UsesPyCallable(PyCallable)) + return Tracker.Delegate; + } + return nullptr; +} + +UPythonDelegate *FUnrealEnginePythonHouseKeeper::NewDelegate(UObject *Owner, PyObject *PyCallable, UFunction *Signature) +{ + UPythonDelegate *Delegate = NewObject(); + + Delegate->AddToRoot(); + Delegate->SetPyCallable(PyCallable); + Delegate->SetSignature(Signature); + + FPythonDelegateTracker Tracker(Delegate, Owner); + PyDelegatesTracker.Add(Tracker); + + return Delegate; +} + +TSharedRef FUnrealEnginePythonHouseKeeper::NewSlateDelegate(TSharedRef Owner, PyObject *PyCallable) +{ + TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); + Delegate->SetPyCallable(PyCallable); + + FPythonSWidgetDelegateTracker Tracker(Delegate, Owner); + PySlateDelegatesTracker.Add(Tracker); + + return Delegate; +} + +TSharedRef FUnrealEnginePythonHouseKeeper::NewDeferredSlateDelegate(PyObject *PyCallable) +{ + TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); + Delegate->SetPyCallable(PyCallable); + + return Delegate; +} + +TSharedRef FUnrealEnginePythonHouseKeeper::NewPythonSmartDelegate(PyObject *PyCallable) +{ + TSharedRef Delegate = MakeShareable(new FPythonSmartDelegate()); + Delegate->SetPyCallable(PyCallable); + + PyStaticSmartDelegatesTracker.Add(Delegate); + + return Delegate; +} + +void FUnrealEnginePythonHouseKeeper::TrackDeferredSlateDelegate(TSharedRef Delegate, TSharedRef Owner) +{ + FPythonSWidgetDelegateTracker Tracker(Delegate, Owner); + PySlateDelegatesTracker.Add(Tracker); +} + +TSharedRef FUnrealEnginePythonHouseKeeper::NewStaticSlateDelegate(PyObject *PyCallable) +{ + TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); + Delegate->SetPyCallable(PyCallable); + + PyStaticSlateDelegatesTracker.Add(Delegate); + + return Delegate; +} + diff --git a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h index dcde4d3a7..ccd9edb01 100644 --- a/Source/UnrealEnginePython/Public/PythonHouseKeeper.h +++ b/Source/UnrealEnginePython/Public/PythonHouseKeeper.h @@ -11,304 +11,72 @@ class FUnrealEnginePythonHouseKeeper : public FGCObject { - - struct FPythonUOjectTracker - { - FWeakObjectPtr Owner; - ue_PyUObject *PyUObject; - bool bPythonOwned; - - FPythonUOjectTracker(UObject *Object, ue_PyUObject *InPyUObject) - { - Owner = FWeakObjectPtr(Object); - PyUObject = InPyUObject; - bPythonOwned = false; - } - }; - - struct FPythonDelegateTracker - { - FWeakObjectPtr Owner; - UPythonDelegate *Delegate; - - FPythonDelegateTracker(UPythonDelegate *DelegateToTrack, UObject *DelegateOwner) : Owner(DelegateOwner), Delegate(DelegateToTrack) - { - } - - ~FPythonDelegateTracker() - { - } - }; - - - struct FPythonSWidgetDelegateTracker - { - TWeakPtr Owner; - TSharedPtr Delegate; - - FPythonSWidgetDelegateTracker(TSharedRef DelegateToTrack, TSharedRef DelegateOwner) : Owner(DelegateOwner), Delegate(DelegateToTrack) - { - } - - ~FPythonSWidgetDelegateTracker() - { - } - }; - -public: - - virtual void AddReferencedObjects(FReferenceCollector& InCollector) override - { - InCollector.AddReferencedObjects(PythonTrackedObjects); - } - - static FUnrealEnginePythonHouseKeeper *Get() - { - static FUnrealEnginePythonHouseKeeper *Singleton; - if (!Singleton) - { - Singleton = new FUnrealEnginePythonHouseKeeper(); - // register a new delegate for the GC -#if ENGINE_MINOR_VERSION >= 18 - FCoreUObjectDelegates::GetPostGarbageCollect().AddRaw(Singleton, &FUnrealEnginePythonHouseKeeper::RunGCDelegate); -#else - FCoreUObjectDelegates::PostGarbageCollect.AddRaw(Singleton, &FUnrealEnginePythonHouseKeeper::RunGCDelegate); -#endif - } - return Singleton; - } - - void RunGCDelegate() - { - FScopePythonGIL gil; - RunGC(); - } - - int32 RunGC() - { - int32 Garbaged = PyUObjectsGC(); - Garbaged += DelegatesGC(); - return Garbaged; - } - - bool IsValidPyUObject(ue_PyUObject *PyUObject) - { - if (!PyUObject) - return false; - - UObject *Object = PyUObject->ue_object; - FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); - if (!Tracker) - { - return false; - } - - if (!Tracker->Owner.IsValid()) - return false; - - return true; - - } - - void TrackUObject(UObject *Object) - { - FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); - if (!Tracker) - { - return; - } - if (Tracker->bPythonOwned) - return; - Tracker->bPythonOwned = true; - // when a new ue_PyUObject spawns, it has a reference counting of two - Py_DECREF(Tracker->PyUObject); - Tracker->PyUObject->owned = 1; - PythonTrackedObjects.Add(Object); - } - - void UntrackUObject(UObject *Object) - { - PythonTrackedObjects.Remove(Object); - } - - void RegisterPyUObject(UObject *Object, ue_PyUObject *InPyUObject) - { - UObjectPyMapping.Add(Object, FPythonUOjectTracker(Object, InPyUObject)); - } - - void UnregisterPyUObject(UObject *Object) - { - UObjectPyMapping.Remove(Object); - } - - ue_PyUObject *GetPyUObject(UObject *Object) - { - FPythonUOjectTracker *Tracker = UObjectPyMapping.Find(Object); - if (!Tracker) - { - return nullptr; - } - - if (!Tracker->Owner.IsValid(true)) - { -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Warning, TEXT("DEFREF'ing UObject at %p (refcnt: %d)"), Object, Tracker->PyUObject->ob_base.ob_refcnt); -#endif - if (!Tracker->bPythonOwned) - Py_DECREF((PyObject *)Tracker->PyUObject); - UnregisterPyUObject(Object); - return nullptr; - } - - return Tracker->PyUObject; -} - - uint32 PyUObjectsGC() - { - uint32 Garbaged = 0; - TArray BrokenList; - for (auto &UObjectPyItem : UObjectPyMapping) - { - UObject *Object = UObjectPyItem.Key; - FPythonUOjectTracker &Tracker = UObjectPyItem.Value; -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Warning, TEXT("Checking for UObject at %p"), Object); -#endif - if (!Tracker.Owner.IsValid(true)) - { -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Warning, TEXT("Removing UObject at %p (refcnt: %d)"), Object, Tracker.PyUObject->ob_base.ob_refcnt); -#endif - BrokenList.Add(Object); - Garbaged++; - } - else - { -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Error, TEXT("UObject at %p %s is in use"), Object, *Object->GetName()); -#endif - } - } - - for (UObject *Object : BrokenList) - { - FPythonUOjectTracker &Tracker = UObjectPyMapping[Object]; - if (!Tracker.bPythonOwned) - Py_DECREF((PyObject *)Tracker.PyUObject); - UnregisterPyUObject(Object); - } - - return Garbaged; - - } - - - int32 DelegatesGC() - { - int32 Garbaged = 0; -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Display, TEXT("Garbage collecting %d UObject delegates"), PyDelegatesTracker.Num()); -#endif - for (int32 i = PyDelegatesTracker.Num() - 1; i >= 0; --i) - { - FPythonDelegateTracker &Tracker = PyDelegatesTracker[i]; - if (!Tracker.Owner.IsValid(true)) - { - Tracker.Delegate->RemoveFromRoot(); - PyDelegatesTracker.RemoveAt(i); - Garbaged++; - } - - } - -#if defined(UEPY_MEMORY_DEBUG) - UE_LOG(LogPython, Display, TEXT("Garbage collecting %d Slate delegates"), PySlateDelegatesTracker.Num()); -#endif - - for (int32 i = PySlateDelegatesTracker.Num() - 1; i >= 0; --i) - { - FPythonSWidgetDelegateTracker &Tracker = PySlateDelegatesTracker[i]; - if (!Tracker.Owner.IsValid()) - { - PySlateDelegatesTracker.RemoveAt(i); - Garbaged++; - } - - } - return Garbaged; - } - - UPythonDelegate *FindDelegate(UObject *Owner, PyObject *PyCallable) + struct FPythonUOjectTracker { - for (int32 i = PyDelegatesTracker.Num() - 1; i >= 0; --i) - { - FPythonDelegateTracker &Tracker = PyDelegatesTracker[i]; - if (Tracker.Owner.Get() == Owner && Tracker.Delegate->UsesPyCallable(PyCallable)) - return Tracker.Delegate; + FWeakObjectPtr Owner; + ue_PyUObject *PyUObject; + bool bPythonOwned; + + FPythonUOjectTracker(UObject *Object, ue_PyUObject *InPyUObject) + { + Owner = FWeakObjectPtr(Object); + PyUObject = InPyUObject; + bPythonOwned = false; } - return nullptr; - } - - UPythonDelegate *NewDelegate(UObject *Owner, PyObject *PyCallable, UFunction *Signature) - { - UPythonDelegate *Delegate = NewObject(); - - Delegate->AddToRoot(); - Delegate->SetPyCallable(PyCallable); - Delegate->SetSignature(Signature); - - FPythonDelegateTracker Tracker(Delegate, Owner); - PyDelegatesTracker.Add(Tracker); + }; - return Delegate; - } - - TSharedRef NewSlateDelegate(TSharedRef Owner, PyObject *PyCallable) - { - TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); - Delegate->SetPyCallable(PyCallable); - - FPythonSWidgetDelegateTracker Tracker(Delegate, Owner); - PySlateDelegatesTracker.Add(Tracker); - - return Delegate; - } - - TSharedRef NewDeferredSlateDelegate(PyObject *PyCallable) - { - TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); - Delegate->SetPyCallable(PyCallable); - - return Delegate; - } + struct FPythonDelegateTracker + { + FWeakObjectPtr Owner; + UPythonDelegate *Delegate; - TSharedRef NewPythonSmartDelegate(PyObject *PyCallable) - { - TSharedRef Delegate = MakeShareable(new FPythonSmartDelegate()); - Delegate->SetPyCallable(PyCallable); + FPythonDelegateTracker(UPythonDelegate *DelegateToTrack, UObject *DelegateOwner) : Owner(DelegateOwner), Delegate(DelegateToTrack) + { + } - PyStaticSmartDelegatesTracker.Add(Delegate); + ~FPythonDelegateTracker() + { + } + }; - return Delegate; - } + struct FPythonSWidgetDelegateTracker + { + TWeakPtr Owner; + TSharedPtr Delegate; - void TrackDeferredSlateDelegate(TSharedRef Delegate, TSharedRef Owner) - { - FPythonSWidgetDelegateTracker Tracker(Delegate, Owner); - PySlateDelegatesTracker.Add(Tracker); - } + FPythonSWidgetDelegateTracker(TSharedRef DelegateToTrack, TSharedRef DelegateOwner) : Owner(DelegateOwner), Delegate(DelegateToTrack) + { + } - TSharedRef NewStaticSlateDelegate(PyObject *PyCallable) - { - TSharedRef Delegate = MakeShareable(new FPythonSlateDelegate()); - Delegate->SetPyCallable(PyCallable); + ~FPythonSWidgetDelegateTracker() + { + } + }; - PyStaticSlateDelegatesTracker.Add(Delegate); +public: - return Delegate; - } + virtual void AddReferencedObjects(FReferenceCollector& InCollector) override; + static FUnrealEnginePythonHouseKeeper *Get(); + int32 RunGC(); + bool IsValidPyUObject(ue_PyUObject *PyUObject); + void TrackUObject(UObject *Object); + void UntrackUObject(UObject *Object); + void RegisterPyUObject(UObject *Object, ue_PyUObject *InPyUObject); + void UnregisterPyUObject(UObject *Object); + ue_PyUObject *GetPyUObject(UObject *Object); + UPythonDelegate *FindDelegate(UObject *Owner, PyObject *PyCallable); + UPythonDelegate *NewDelegate(UObject *Owner, PyObject *PyCallable, UFunction *Signature); + TSharedRef NewSlateDelegate(TSharedRef Owner, PyObject *PyCallable); + TSharedRef NewDeferredSlateDelegate(PyObject *PyCallable); + TSharedRef NewPythonSmartDelegate(PyObject *PyCallable); + void TrackDeferredSlateDelegate(TSharedRef Delegate, TSharedRef Owner); + TSharedRef NewStaticSlateDelegate(PyObject *PyCallable); private: + void RunGCDelegate(); + uint32 PyUObjectsGC(); + int32 DelegatesGC(); + TMap UObjectPyMapping; TArray PyDelegatesTracker; diff --git a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs index 48d6618c1..51394b033 100644 --- a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs +++ b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs @@ -107,9 +107,6 @@ public UnrealEnginePython(TargetInfo Target) PrivateIncludePaths.AddRange( new string[] { -#if !UE_4_22_OR_LATER - "UnrealEnginePython/Private", -#endif // ... add other private include paths required here ... } ); From 79aef1e4c78497495f574790962dd835c269ca58 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Tue, 23 Apr 2019 16:21:14 +0200 Subject: [PATCH 08/23] fixed non editor build --- Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp index ec2be2b7c..61cf5c247 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp @@ -316,8 +316,11 @@ PyObject *py_ue_set_current_level(ue_PyUObject *self, PyObject * args) if (!level) return PyErr_Format(PyExc_Exception, "argument is not a ULevel"); +#if WITH_EDITOR + if (world->SetCurrentLevel(level)) Py_RETURN_TRUE; +#endif Py_RETURN_FALSE; } From 62016f5eaa0d7f8481d7943b4c15aa1b119fee37 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Tue, 23 Apr 2019 16:23:45 +0200 Subject: [PATCH 09/23] fix for 4.22 --- Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp index 61cf5c247..19a31299b 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp @@ -316,7 +316,7 @@ PyObject *py_ue_set_current_level(ue_PyUObject *self, PyObject * args) if (!level) return PyErr_Format(PyExc_Exception, "argument is not a ULevel"); -#if WITH_EDITOR +#if WITH_EDITOR || ENGINE_MINOR_VERSION < 22 if (world->SetCurrentLevel(level)) Py_RETURN_TRUE; From 76ae4b11bfd1cf46db0b191657c0ec2263b12741 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Fri, 26 Apr 2019 18:02:14 +0200 Subject: [PATCH 10/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46264da12..17e845c1c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole' All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell) -The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20 and 4.21 +The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20, 4.21 and 4.22 We support official python.org releases as well as IntelPython and Anaconda distributions. From 2b92282224328c06d81ca2635eab605a5b54d19c Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Wed, 8 May 2019 10:14:01 +0200 Subject: [PATCH 11/23] added 4.22 to automatic build system --- tools/release_win64.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release_win64.py b/tools/release_win64.py index bee239f42..4ea5beb89 100644 --- a/tools/release_win64.py +++ b/tools/release_win64.py @@ -5,7 +5,7 @@ import shutil import zipfile -UE_VERSIONS = ['4.15', '4.16', '4.17', '4.18', '4.19', '4.20', '4.21'] +UE_VERSIONS = ['4.17', '4.18', '4.19', '4.20', '4.21', '4.22'] PYTHON_VERSIONS = ["C:/Program Files/Python37", "C:/Program Files/Python36", "C:/Python27"] MSBUILD = 'C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/Bin/MSBuild.exe' UE_PATH = 'C:/Program Files/Epic Games' From 282eaa5f7730f96541cc706b05952a8bf814e92c Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Wed, 8 May 2019 11:25:28 +0200 Subject: [PATCH 12/23] start from 4.20 for automatic builds --- tools/release_win64.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release_win64.py b/tools/release_win64.py index 4ea5beb89..057800496 100644 --- a/tools/release_win64.py +++ b/tools/release_win64.py @@ -5,7 +5,7 @@ import shutil import zipfile -UE_VERSIONS = ['4.17', '4.18', '4.19', '4.20', '4.21', '4.22'] +UE_VERSIONS = ['4.20', '4.21', '4.22'] PYTHON_VERSIONS = ["C:/Program Files/Python37", "C:/Program Files/Python36", "C:/Python27"] MSBUILD = 'C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/Bin/MSBuild.exe' UE_PATH = 'C:/Program Files/Epic Games' From 6a43ea4f250a39f9ad1686dfd90770d9ae4ea8f3 Mon Sep 17 00:00:00 2001 From: Elvis Dowson Date: Tue, 4 Jun 2019 11:58:03 +0400 Subject: [PATCH 13/23] .gitignore: Ignore Intermediate folder. Signed-off-by: Elvis Dowson --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a8f0b03d6..e43464f53 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ ENV/ .ropeproject Binaries/ +Intermediate/ python35/ python27/ *.un~ From 02dd03dfd26f72d3d6252febff1d79bdb037cf97 Mon Sep 17 00:00:00 2001 From: Elvis Dowson Date: Tue, 4 Jun 2019 12:02:04 +0400 Subject: [PATCH 14/23] PythonHouseKeeper: Fix compile error: #pragma once in main file This commit fixes the following error: PythonHouseKeeper.cpp:1:9: error: #pragma once in main file [-Werror,-Wpragma-once-outside-header] #pragma once ^ Signed-off-by: Elvis Dowson --- Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp b/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp index ea9d5dda3..dc014e386 100644 --- a/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp +++ b/Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp @@ -1,4 +1,3 @@ -#pragma once #include "PythonHouseKeeper.h" From e928f718c3f6ba82998f681f58f07ebc101db93f Mon Sep 17 00:00:00 2001 From: Elvis Dowson Date: Tue, 4 Jun 2019 12:03:18 +0400 Subject: [PATCH 15/23] PythonAutomationModule: Update for UE4.22. Signed-off-by: Elvis Dowson --- Source/PythonAutomation/Public/PythonAutomationModule.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/PythonAutomation/Public/PythonAutomationModule.h b/Source/PythonAutomation/Public/PythonAutomationModule.h index c0f9c6d16..bc19a062e 100644 --- a/Source/PythonAutomation/Public/PythonAutomationModule.h +++ b/Source/PythonAutomation/Public/PythonAutomationModule.h @@ -3,7 +3,11 @@ #pragma once #include "CoreMinimal.h" +#if ENGINE_MAJOR_VERSION==4 && ENGINE_MINOR_VERSION>=22 +#include "Modules/ModuleInterface.h" +#else #include "ModuleInterface.h" +#endif class FPythonAutomationModule : public IModuleInterface { From bc4b7915125d5e78b3a65dd1df00f1fdf0ad00c3 Mon Sep 17 00:00:00 2001 From: Fabian Elmers Date: Fri, 14 Jun 2019 14:36:07 -0700 Subject: [PATCH 16/23] Adding edgraph functions graph_reconstruct_node() and graph_remove_node() --- .../Private/Blueprint/UEPyEdGraph.cpp | 121 ++++++++++++++++++ .../Private/Blueprint/UEPyEdGraph.h | 3 + .../UnrealEnginePython/Private/UEPyModule.cpp | 3 + 3 files changed, 127 insertions(+) diff --git a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.cpp b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.cpp index 6f75053ba..a3e53b7c5 100644 --- a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.cpp +++ b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.cpp @@ -381,6 +381,127 @@ PyObject *py_ue_graph_add_node(ue_PyUObject * self, PyObject * args) Py_RETURN_UOBJECT(node); } +PyObject *py_ue_graph_remove_node(ue_PyUObject * self, PyObject * args) +{ + + ue_py_check(self); + + PyObject *py_node_class; + int x = 0; + int y = 0; + + char *metadata = nullptr; + PyObject *py_data = nullptr; + + if (!PyArg_ParseTuple(args, "O|iisO:graph_remove_node", &py_node_class, &x, &y, &metadata, &py_data)) + { + return nullptr; + } + + UEdGraph *graph = ue_py_check_type(self); + if (!graph) + return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph"); + + UObject *u_obj = ue_py_check_type(py_node_class); + if (!u_obj) + return PyErr_Format(PyExc_Exception, "argument is not a UObject"); + + UEdGraphNode *node = nullptr; + + if (UClass *u_class = Cast(u_obj)) + { + if (!u_class->IsChildOf()) + { + return PyErr_Format(PyExc_Exception, "argument is not a child of UEdGraphNode"); + } + node = NewObject(graph, u_class); + node->PostLoad(); + } + else + { + node = Cast(u_obj); + if (node) + { + if (node->GetOuter() != graph) + + node->Rename(*node->GetName(), graph); + } + } + + if (!node) + return PyErr_Format(PyExc_Exception, "argument is not a supported type"); + + graph->RemoveNode(node); + + if (UBlueprint *bp = Cast(node->GetGraph()->GetOuter())) + { + FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp); + } + + Py_RETURN_NONE; +} + +PyObject *py_ue_graph_reconstruct_node(ue_PyUObject * self, PyObject * args) +{ + + ue_py_check(self); + + PyObject *py_node_class; + int x = 0; + int y = 0; + + char *metadata = nullptr; + PyObject *py_data = nullptr; + + if (!PyArg_ParseTuple(args, "O|iisO:graph_reconstruct_node", &py_node_class, &x, &y, &metadata, &py_data)) + { + return nullptr; + } + + UEdGraph *graph = ue_py_check_type(self); + if (!graph) + return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph"); + + UObject *u_obj = ue_py_check_type(py_node_class); + if (!u_obj) + return PyErr_Format(PyExc_Exception, "argument is not a UObject"); + + UEdGraphNode *node = nullptr; + + if (UClass *u_class = Cast(u_obj)) + { + if (!u_class->IsChildOf()) + { + return PyErr_Format(PyExc_Exception, "argument is not a child of UEdGraphNode"); + } + node = NewObject(graph, u_class); + node->PostLoad(); + } + else + { + node = Cast(u_obj); + if (node) + { + if (node->GetOuter() != graph) + + node->Rename(*node->GetName(), graph); + } + } + + if (!node) + return PyErr_Format(PyExc_Exception, "argument is not a supported type"); + + //graph->RemoveNode(node); + node->ReconstructNode(); + + if (UBlueprint *bp = Cast(node->GetGraph()->GetOuter())) + { + FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp); + } + + Py_RETURN_NONE; +} + PyObject *py_ue_graph_add_node_dynamic_cast(ue_PyUObject * self, PyObject * args) { diff --git a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.h b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.h index 03061426b..e0fd0fe69 100644 --- a/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.h +++ b/Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.h @@ -16,6 +16,9 @@ PyObject *py_ue_graph_add_node(ue_PyUObject *, PyObject *); PyObject *py_ue_graph_add_node_dynamic_cast(ue_PyUObject *, PyObject *); PyObject *py_ue_graph_add_node_event(ue_PyUObject *, PyObject *); +PyObject *py_ue_graph_reconstruct_node(ue_PyUObject *, PyObject *); +PyObject *py_ue_graph_remove_node(ue_PyUObject *, PyObject *); + PyObject *py_ue_graph_get_good_place_for_new_node(ue_PyUObject *, PyObject *); PyObject *py_ue_node_pins(ue_PyUObject *, PyObject *); diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index 993828a86..66aab749b 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -664,6 +664,9 @@ static PyMethodDef ue_PyUObject_methods[] = { { "graph_add_node_event", (PyCFunction)py_ue_graph_add_node_event, METH_VARARGS, "" }, { "graph_get_good_place_for_new_node", (PyCFunction)py_ue_graph_get_good_place_for_new_node, METH_VARARGS, "" }, + { "graph_reconstruct_node", (PyCFunction)py_ue_graph_reconstruct_node, METH_VARARGS, "" }, + { "graph_remove_node", (PyCFunction)py_ue_graph_remove_node, METH_VARARGS, "" }, + { "node_pins", (PyCFunction)py_ue_node_pins, METH_VARARGS, "" }, { "node_get_title", (PyCFunction)py_ue_node_get_title, METH_VARARGS, "" }, { "node_find_pin", (PyCFunction)py_ue_node_find_pin, METH_VARARGS, "" }, From 15f9eea0caddaa0d8237e260de9f63d039282fbc Mon Sep 17 00:00:00 2001 From: Michael Chapman Date: Sun, 30 Jun 2019 01:51:37 +1000 Subject: [PATCH 17/23] Add remove_component_from_blueprint Add support for removing components from blueprints to compliment existing add component functionality --- .../UnrealEnginePython/Private/UEPyEditor.cpp | 31 +++++++++++++++++++ .../UnrealEnginePython/Private/UEPyEditor.h | 1 + .../UnrealEnginePython/Private/UEPyModule.cpp | 1 + 3 files changed, 33 insertions(+) diff --git a/Source/UnrealEnginePython/Private/UEPyEditor.cpp b/Source/UnrealEnginePython/Private/UEPyEditor.cpp index e994cf121..1b3df7bca 100644 --- a/Source/UnrealEnginePython/Private/UEPyEditor.cpp +++ b/Source/UnrealEnginePython/Private/UEPyEditor.cpp @@ -1473,6 +1473,37 @@ PyObject *py_unreal_engine_get_blueprint_components(PyObject * self, PyObject * } +PyObject *py_unreal_engine_remove_component_from_blueprint(PyObject *self, PyObject *args) +{ + PyObject *py_blueprint; + char *name; + char *parentName = nullptr; + + if (!PyArg_ParseTuple(args, "Os|s:remove_component_from_blueprint", &py_blueprint, &name, &parentName)) + { + return NULL; + } + + if (!ue_is_pyuobject(py_blueprint)) + { + return PyErr_Format(PyExc_Exception, "argument is not a UObject"); + } + + ue_PyUObject *py_obj = (ue_PyUObject *)py_blueprint; + if (!py_obj->ue_object->IsA()) + return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint"); + UBlueprint *bp = (UBlueprint *)py_obj->ue_object; + + bp->Modify(); + USCS_Node *ComponentNode = bp->SimpleConstructionScript->FindSCSNode(UTF8_TO_TCHAR(name)); + if (ComponentNode) + { + bp->SimpleConstructionScript->RemoveNode(ComponentNode); + } + + Py_RETURN_NONE; +} + PyObject *py_unreal_engine_add_component_to_blueprint(PyObject * self, PyObject * args) { diff --git a/Source/UnrealEnginePython/Private/UEPyEditor.h b/Source/UnrealEnginePython/Private/UEPyEditor.h index 788a76ad3..31c8028e1 100644 --- a/Source/UnrealEnginePython/Private/UEPyEditor.h +++ b/Source/UnrealEnginePython/Private/UEPyEditor.h @@ -52,6 +52,7 @@ PyObject *py_unreal_engine_reload_blueprint(PyObject *, PyObject *); PyObject *py_unreal_engine_replace_blueprint(PyObject *, PyObject *); PyObject *py_unreal_engine_create_blueprint_from_actor(PyObject *, PyObject *); PyObject *py_unreal_engine_add_component_to_blueprint(PyObject *, PyObject *); +PyObject *py_unreal_engine_remove_component_from_blueprint(PyObject *, PyObject *); PyObject *py_unreal_engine_blueprint_add_member_variable(PyObject *, PyObject *); PyObject *py_unreal_engine_blueprint_add_new_timeline(PyObject *, PyObject *); diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index 993828a86..ed7a1d4b8 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -389,6 +389,7 @@ static PyMethodDef unreal_engine_methods[] = { { "blueprint_get_all_graphs", py_unreal_engine_blueprint_get_all_graphs, METH_VARARGS, "" }, { "blueprint_mark_as_structurally_modified", py_unreal_engine_blueprint_mark_as_structurally_modified, METH_VARARGS, "" }, { "add_component_to_blueprint", py_unreal_engine_add_component_to_blueprint, METH_VARARGS, "" }, + { "remove_component_from_blueprint", py_unreal_engine_remove_component_from_blueprint, METH_VARARGS, "" }, { "get_blueprint_components", py_unreal_engine_get_blueprint_components, METH_VARARGS, "" }, { "create_material_instance", py_unreal_engine_create_material_instance, METH_VARARGS, "" }, { "message_dialog_open", py_unreal_engine_message_dialog_open, METH_VARARGS, "" }, From 7b33998d15fb77a386b21b3d219ac7f0efe7b88e Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Mon, 9 Sep 2019 07:46:55 +0200 Subject: [PATCH 18/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17e845c1c..ee231ff61 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole' All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell) -The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20, 4.21 and 4.22 +The minimal supported Unreal Engine version is 4.12, while the latest is 4.23 We support official python.org releases as well as IntelPython and Anaconda distributions. From 11d550b62272844b8dcd28c9bfe5ddd92ff20ab4 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Tue, 10 Sep 2019 19:33:39 +0200 Subject: [PATCH 19/23] first round of 4.23 patches --- .../Private/Slate/UEPyFMenuBuilder.cpp | 76 +-- .../UnrealEnginePython/Private/UEPyModule.cpp | 559 +++++++++--------- .../Private/UEPySubclassing.cpp | 9 + .../Private/UObject/UEPyAnimSequence.cpp | 2 + .../Private/UObject/UEPyFoliage.cpp | 17 +- .../Private/UObject/UEPyLandscape.cpp | 33 +- .../Private/UObject/UEPyMaterial.cpp | 4 + .../Private/Wrappers/UEPyESlateEnums.cpp | 4 + .../Private/Wrappers/UEPyFFoliageInstance.cpp | 80 +-- .../UnrealEnginePython.Build.cs | 2 +- 10 files changed, 432 insertions(+), 354 deletions(-) diff --git a/Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp b/Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp index 3157ec4f0..3e0b978ed 100644 --- a/Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp +++ b/Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp @@ -2,10 +2,10 @@ #include "Wrappers/UEPyESlateEnums.h" -static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder* self, PyObject* args) { - char *name; - char *text; + char* name; + char* text; if (!PyArg_ParseTuple(args, "ss:begin_section", &name, &text)) return nullptr; @@ -14,27 +14,31 @@ static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyOb Py_RETURN_NONE; } -static PyObject *py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder* self, PyObject* args) { self->menu_builder.EndSection(); Py_RETURN_NONE; } -static PyObject *py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder* self, PyObject* args) { - ue_PySWidget *ret = (ue_PySWidget *)PyObject_New(ue_PySWidget, &ue_PySWidgetType); + ue_PySWidget* ret = (ue_PySWidget*)PyObject_New(ue_PySWidget, &ue_PySWidgetType); new (&ret->Widget) TSharedRef(self->menu_builder.MakeWidget()); - return (PyObject *)ret; + return (PyObject*)ret; } -static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder* self, PyObject* args) { - char *label; - char *tooltip; - PyObject *py_callable; - PyObject *py_obj = nullptr; + char* label; + char* tooltip; + PyObject* py_callable; + PyObject* py_obj = nullptr; +#if ENGINE_MINOR_VERSION >= 23 + int ui_action_type = (int)EUserInterfaceActionType::Button; +#else int ui_action_type = EUserInterfaceActionType::Button; +#endif if (!PyArg_ParseTuple(args, "ssO|Oi:add_menu_entry", &label, &tooltip, &py_callable, &py_obj, &ui_action_type)) return nullptr; @@ -58,17 +62,21 @@ static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyO } self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler), NAME_None, +#if ENGINE_MINOR_VERSION >= 23 + (EUserInterfaceActionType)ui_action_type); +#else (EUserInterfaceActionType::Type)ui_action_type); +#endif Py_RETURN_NONE; } -static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder* self, PyObject* args) { - char *label; - char *tooltip; - PyObject *py_callable; - PyObject *py_bool = nullptr; + char* label; + char* tooltip; + PyObject* py_callable; + PyObject* py_bool = nullptr; if (!PyArg_ParseTuple(args, "ssO|O:add_sub_menu", &label, &tooltip, &py_callable, &py_bool)) return nullptr; @@ -77,7 +85,7 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj return PyErr_Format(PyExc_Exception, "argument is not callable"); } - + TSharedRef py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callable); FNewMenuDelegate menu_delegate; @@ -89,9 +97,9 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj Py_RETURN_NONE; } -static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder* self, PyObject* args) { - char *name = nullptr; + char* name = nullptr; if (!PyArg_ParseTuple(args, "|s:add_menu_separator", &name)) return nullptr; @@ -107,9 +115,9 @@ static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, } #if WITH_EDITOR -static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder* self, PyObject* args) { - PyObject *py_assets; + PyObject* py_assets; if (!PyArg_ParseTuple(args, "O:add_asset_actions", &py_assets)) return nullptr; @@ -120,10 +128,10 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, return PyErr_Format(PyExc_Exception, "argument is not iterable"); } - TArray u_objects; - while (PyObject *item = PyIter_Next(py_assets)) + TArray u_objects; + while (PyObject * item = PyIter_Next(py_assets)) { - UObject *u_object = ue_py_check_type(item); + UObject* u_object = ue_py_check_type(item); if (u_object) { u_objects.Add(u_object); @@ -142,7 +150,7 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, } #endif -static PyObject *py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder *self, PyObject * args) +static PyObject* py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder* self, PyObject* args) { self->menu_builder.AddSearchWidget(); @@ -164,13 +172,13 @@ static PyMethodDef ue_PyFMenuBuilder_methods[] = { }; -static PyObject *ue_PyFMenuBuilder_str(ue_PyFMenuBuilder *self) +static PyObject* ue_PyFMenuBuilder_str(ue_PyFMenuBuilder* self) { return PyUnicode_FromFormat("", &self->menu_builder); } -static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder *self) +static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder* self) { #if PY_MAJOR_VERSION < 3 self->ob_type->tp_free((PyObject*)self); @@ -210,14 +218,14 @@ static PyTypeObject ue_PyFMenuBuilderType = { ue_PyFMenuBuilder_methods, /* tp_methods */ }; -static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs) +static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder* self, PyObject* args, PyObject* kwargs) { new(&self->menu_builder) FMenuBuilder(true, nullptr); return 0; } -void ue_python_init_fmenu_builder(PyObject *ue_module) +void ue_python_init_fmenu_builder(PyObject* ue_module) { ue_PyFMenuBuilderType.tp_new = PyType_GenericNew; @@ -227,12 +235,12 @@ void ue_python_init_fmenu_builder(PyObject *ue_module) return; Py_INCREF(&ue_PyFMenuBuilderType); - PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject *)&ue_PyFMenuBuilderType); + PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject*)& ue_PyFMenuBuilderType); } -PyObject *py_ue_new_fmenu_builder(FMenuBuilder menu_builder) +PyObject* py_ue_new_fmenu_builder(FMenuBuilder menu_builder) { - ue_PyFMenuBuilder *ret = (ue_PyFMenuBuilder *)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType); + ue_PyFMenuBuilder* ret = (ue_PyFMenuBuilder*)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType); new(&ret->menu_builder) FMenuBuilder(menu_builder); - return (PyObject *)ret; + return (PyObject*)ret; } diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index e02525792..b725ae7f0 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -137,7 +137,7 @@ static PyModuleDef unreal_engine_module = { -1, NULL, }; -static PyObject *init_unreal_engine(void); +static PyObject* init_unreal_engine(void); @@ -148,21 +148,21 @@ void init_unreal_engine_builtin() #endif -static PyObject *py_unreal_engine_py_gc(PyObject * self, PyObject * args) +static PyObject* py_unreal_engine_py_gc(PyObject* self, PyObject* args) { int32 Garbaged = FUnrealEnginePythonHouseKeeper::Get()->RunGC(); return PyLong_FromLong(Garbaged); } -static PyObject *py_unreal_engine_exec(PyObject * self, PyObject * args) +static PyObject* py_unreal_engine_exec(PyObject* self, PyObject* args) { - char *filename = nullptr; + char* filename = nullptr; if (!PyArg_ParseTuple(args, "s:exec", &filename)) { return NULL; } - FUnrealEnginePythonModule &PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); + FUnrealEnginePythonModule& PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); Py_BEGIN_ALLOW_THREADS; PythonModule.RunFile(filename); Py_END_ALLOW_THREADS; @@ -171,14 +171,14 @@ static PyObject *py_unreal_engine_exec(PyObject * self, PyObject * args) #if PLATFORM_MAC -static PyObject *py_unreal_engine_exec_in_main_thread(PyObject * self, PyObject * args) +static PyObject* py_unreal_engine_exec_in_main_thread(PyObject* self, PyObject* args) { - char *filename = nullptr; + char* filename = nullptr; if (!PyArg_ParseTuple(args, "s:exec_in_main_thread", &filename)) { return NULL; } - FUnrealEnginePythonModule &PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); + FUnrealEnginePythonModule& PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); Py_BEGIN_ALLOW_THREADS; PythonModule.RunFileInMainThread(filename); Py_END_ALLOW_THREADS; @@ -186,7 +186,7 @@ static PyObject *py_unreal_engine_exec_in_main_thread(PyObject * self, PyObject } #endif -static PyObject *py_ue_get_py_proxy(ue_PyUObject *self, PyObject * args) +static PyObject* py_ue_get_py_proxy(ue_PyUObject* self, PyObject* args) { ue_py_check(self); @@ -194,13 +194,13 @@ static PyObject *py_ue_get_py_proxy(ue_PyUObject *self, PyObject * args) if (self->py_proxy) { Py_INCREF(self->py_proxy); - return (PyObject *)self->py_proxy; + return (PyObject*)self->py_proxy; } Py_RETURN_NONE; } -static PyObject *py_unreal_engine_shutdown(PyObject *self, PyObject * args) +static PyObject* py_unreal_engine_shutdown(PyObject* self, PyObject* args) { GIsRequestingExit = true; @@ -208,10 +208,10 @@ static PyObject *py_unreal_engine_shutdown(PyObject *self, PyObject * args) Py_RETURN_NONE; } -static PyObject *py_unreal_engine_set_brutal_finalize(PyObject *self, PyObject * args) +static PyObject* py_unreal_engine_set_brutal_finalize(PyObject* self, PyObject* args) { - PyObject *py_bool = nullptr; + PyObject* py_bool = nullptr; if (!PyArg_ParseTuple(args, "|O:set_brutal_finalize", &py_bool)) { return nullptr; @@ -219,7 +219,7 @@ static PyObject *py_unreal_engine_set_brutal_finalize(PyObject *self, PyObject * bool bBrutalFinalize = !py_bool || PyObject_IsTrue(py_bool); - FUnrealEnginePythonModule &PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); + FUnrealEnginePythonModule& PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); PythonModule.BrutalFinalize = bBrutalFinalize; Py_RETURN_NONE; } @@ -757,7 +757,7 @@ static PyMethodDef ue_PyUObject_methods[] = { { "vlog_cylinder", (PyCFunction)py_ue_vlog_cylinder, METH_VARARGS, "" }, // StaticMesh - { "get_static_mesh_bounds", (PyCFunction)py_ue_static_mesh_get_bounds, METH_VARARGS, "" }, + { "get_static_mesh_bounds", (PyCFunction)py_ue_static_mesh_get_bounds, METH_VARARGS, "" }, #if WITH_EDITOR { "static_mesh_build", (PyCFunction)py_ue_static_mesh_build, METH_VARARGS, "" }, { "static_mesh_create_body_setup", (PyCFunction)py_ue_static_mesh_create_body_setup, METH_VARARGS, "" }, @@ -1181,7 +1181,7 @@ static PyMethodDef ue_PyUObject_methods[] = { // destructor -static void ue_pyobject_dealloc(ue_PyUObject *self) +static void ue_pyobject_dealloc(ue_PyUObject* self) { #if defined(UEPY_MEMORY_DEBUG) UE_LOG(LogPython, Warning, TEXT("Destroying ue_PyUObject %p mapped to UObject %p"), self, self->ue_object); @@ -1198,38 +1198,38 @@ static void ue_pyobject_dealloc(ue_PyUObject *self) Py_XDECREF(self->py_dict); - Py_TYPE(self)->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject*)self); } -static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name) +static PyObject* ue_PyUObject_getattro(ue_PyUObject* self, PyObject* attr_name) { ue_py_check(self); - PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, attr_name); + PyObject* ret = PyObject_GenericGetAttr((PyObject*)self, attr_name); if (!ret) { if (PyUnicodeOrString_Check(attr_name)) { - const char *attr = UEPyUnicode_AsUTF8(attr_name); + const char* attr = UEPyUnicode_AsUTF8(attr_name); // first check for property - UStruct *u_struct = nullptr; + UStruct* u_struct = nullptr; if (self->ue_object->IsA()) { - u_struct = (UStruct *)self->ue_object; + u_struct = (UStruct*)self->ue_object; } else { - u_struct = (UStruct *)self->ue_object->GetClass(); + u_struct = (UStruct*)self->ue_object->GetClass(); } - UProperty *u_property = u_struct->FindPropertyByName(FName(UTF8_TO_TCHAR(attr))); + UProperty* u_property = u_struct->FindPropertyByName(FName(UTF8_TO_TCHAR(attr))); if (u_property) { // swallow previous exception PyErr_Clear(); - return ue_py_convert_property(u_property, (uint8 *)self->ue_object, 0); + return ue_py_convert_property(u_property, (uint8*)self->ue_object, 0); } - UFunction *function = self->ue_object->FindFunction(FName(UTF8_TO_TCHAR(attr))); + UFunction* function = self->ue_object->FindFunction(FName(UTF8_TO_TCHAR(attr))); // retry wth K2_ prefix if (!function) { @@ -1242,8 +1242,8 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name) { if (self->ue_object->IsA()) { - UClass *u_class = (UClass *)self->ue_object; - UObject *cdo = u_class->GetDefaultObject(); + UClass* u_class = (UClass*)self->ue_object; + UObject* cdo = u_class->GetDefaultObject(); if (cdo) { function = cdo->FindFunction(FName(UTF8_TO_TCHAR(attr))); @@ -1263,7 +1263,7 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name) #if ENGINE_MINOR_VERSION >= 15 if (self->ue_object->IsA()) { - UUserDefinedEnum *u_enum = (UUserDefinedEnum *)self->ue_object; + UUserDefinedEnum* u_enum = (UUserDefinedEnum*)self->ue_object; PyErr_Clear(); FString attr_as_string = FString(UTF8_TO_TCHAR(attr)); for (auto item : u_enum->DisplayNameMap) @@ -1282,7 +1282,7 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name) #endif if (self->ue_object->IsA()) { - UEnum *u_enum = (UEnum *)self->ue_object; + UEnum* u_enum = (UEnum*)self->ue_object; PyErr_Clear(); #if ENGINE_MINOR_VERSION > 15 int32 value = u_enum->GetIndexByName(FName(UTF8_TO_TCHAR(attr))); @@ -1309,25 +1309,25 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name) return ret; } -static int ue_PyUObject_setattro(ue_PyUObject *self, PyObject *attr_name, PyObject *value) +static int ue_PyUObject_setattro(ue_PyUObject* self, PyObject* attr_name, PyObject* value) { ue_py_check_int(self); // first of all check for UProperty if (PyUnicodeOrString_Check(attr_name)) { - const char *attr = UEPyUnicode_AsUTF8(attr_name); + const char* attr = UEPyUnicode_AsUTF8(attr_name); // first check for property - UStruct *u_struct = nullptr; + UStruct* u_struct = nullptr; if (self->ue_object->IsA()) { - u_struct = (UStruct *)self->ue_object; + u_struct = (UStruct*)self->ue_object; } else { - u_struct = (UStruct *)self->ue_object->GetClass(); + u_struct = (UStruct*)self->ue_object->GetClass(); } - UProperty *u_property = u_struct->FindPropertyByName(FName(UTF8_TO_TCHAR(attr))); + UProperty* u_property = u_struct->FindPropertyByName(FName(UTF8_TO_TCHAR(attr))); if (u_property) { #if WITH_EDITOR @@ -1341,9 +1341,9 @@ static int ue_PyUObject_setattro(ue_PyUObject *self, PyObject *attr_name, PyObje if (self->ue_object->HasAnyFlags(RF_ArchetypeObject | RF_ClassDefaultObject)) { - TArray Instances; + TArray Instances; self->ue_object->GetArchetypeInstances(Instances); - for (UObject *Instance : Instances) + for (UObject* Instance : Instances) { Instance->PreEditChange(u_property); if (ue_py_convert_pyobject(value, u_property, (uint8*)Instance, 0)) @@ -1372,10 +1372,10 @@ static int ue_PyUObject_setattro(ue_PyUObject *self, PyObject *attr_name, PyObje return -1; } } - return PyObject_GenericSetAttr((PyObject *)self, attr_name, value); + return PyObject_GenericSetAttr((PyObject*)self, attr_name, value); } -static PyObject *ue_PyUObject_str(ue_PyUObject *self) +static PyObject* ue_PyUObject_str(ue_PyUObject* self) { ue_py_check(self); @@ -1388,13 +1388,13 @@ static PyObject *ue_PyUObject_str(ue_PyUObject *self) #endif } -static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject *kw) +static PyObject* ue_PyUObject_call(ue_PyUObject* self, PyObject* args, PyObject* kw) { ue_py_check(self); // if it is a class, create a new object if (self->ue_object->IsA()) { - UClass *u_class = (UClass *)self->ue_object; + UClass* u_class = (UClass*)self->ue_object; if (u_class->HasAnyClassFlags(CLASS_Abstract)) { return PyErr_Format(PyExc_Exception, "abstract classes cannot be instantiated"); @@ -1403,16 +1403,16 @@ static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject { return PyErr_Format(PyExc_Exception, "you cannot use __call__ on actors, they have to be spawned"); } - PyObject *py_name = nullptr; - PyObject *py_outer = Py_None; + PyObject* py_name = nullptr; + PyObject* py_outer = Py_None; if (!PyArg_ParseTuple(args, "|OO:new_object", &py_name, &py_outer)) { return NULL; } int num_args = py_name ? 3 : 1; - PyObject *py_args = PyTuple_New(num_args); - Py_INCREF((PyObject *)self); - PyTuple_SetItem(py_args, 0, (PyObject *)self); + PyObject* py_args = PyTuple_New(num_args); + Py_INCREF((PyObject*)self); + PyTuple_SetItem(py_args, 0, (PyObject*)self); if (py_name) { Py_INCREF(py_outer); @@ -1420,7 +1420,7 @@ static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject Py_INCREF(py_name); PyTuple_SetItem(py_args, 2, py_name); } - ue_PyUObject *ret = (ue_PyUObject *)py_unreal_engine_new_object(nullptr, py_args); + ue_PyUObject* ret = (ue_PyUObject*)py_unreal_engine_new_object(nullptr, py_args); Py_DECREF(py_args); if (!ret) { @@ -1430,23 +1430,23 @@ static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject // UObject crated explicitely from python, will be managed by python... FUnrealEnginePythonHouseKeeper::Get()->TrackUObject(ret->ue_object); - return (PyObject *)ret; + return (PyObject*)ret; } // if it is a uscriptstruct, instantiate a new struct if (self->ue_object->IsA()) { - UScriptStruct *u_script_struct = (UScriptStruct *)self->ue_object; - uint8 *data = (uint8*)FMemory::Malloc(u_script_struct->GetStructureSize()); + UScriptStruct* u_script_struct = (UScriptStruct*)self->ue_object; + uint8* data = (uint8*)FMemory::Malloc(u_script_struct->GetStructureSize()); u_script_struct->InitializeStruct(data); #if WITH_EDITOR u_script_struct->InitializeDefaultValue(data); #endif if (kw) { - PyObject *struct_keys = PyObject_GetIter(kw); + PyObject* struct_keys = PyObject_GetIter(kw); for (;;) { - PyObject *key = PyIter_Next(struct_keys); + PyObject* key = PyIter_Next(struct_keys); if (!key) { if (PyErr_Occurred()) @@ -1458,9 +1458,9 @@ static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject } if (!PyUnicodeOrString_Check(key)) continue; - const char *struct_key = UEPyUnicode_AsUTF8(key); + const char* struct_key = UEPyUnicode_AsUTF8(key); - PyObject *value = PyDict_GetItem(kw, key); + PyObject* value = PyDict_GetItem(kw, key); if (!value) { if (PyErr_Occurred()) @@ -1471,7 +1471,7 @@ static PyObject *ue_PyUObject_call(ue_PyUObject *self, PyObject *args, PyObject break; } - UProperty *u_property = ue_struct_get_field_from_name(u_script_struct, (char *)struct_key); + UProperty* u_property = ue_struct_get_field_from_name(u_script_struct, (char*)struct_key); if (u_property) { if (!ue_py_convert_pyobject(value, u_property, data, 0)) @@ -1529,12 +1529,12 @@ static PyTypeObject ue_PyUObjectType = { -UClass *unreal_engine_new_uclass(char *name, UClass *outer_parent) +UClass* unreal_engine_new_uclass(char* name, UClass* outer_parent) { bool is_overwriting = false; - UObject *outer = GetTransientPackage(); - UClass *parent = UObject::StaticClass(); + UObject* outer = GetTransientPackage(); + UClass* parent = UObject::StaticClass(); if (outer_parent) { @@ -1542,7 +1542,7 @@ UClass *unreal_engine_new_uclass(char *name, UClass *outer_parent) outer = parent->GetOuter(); } - UClass *new_object = FindObject(ANY_PACKAGE, UTF8_TO_TCHAR(name)); + UClass* new_object = FindObject(ANY_PACKAGE, UTF8_TO_TCHAR(name)); if (!new_object) { new_object = NewObject(outer, UTF8_TO_TCHAR(name), RF_Public | RF_Transient | RF_MarkAsNative); @@ -1557,13 +1557,13 @@ UClass *unreal_engine_new_uclass(char *name, UClass *outer_parent) if (is_overwriting && new_object->Children) { - UField *u_field = new_object->Children; + UField* u_field = new_object->Children; while (u_field) { if (u_field->IsA()) { UE_LOG(LogPython, Warning, TEXT("removing function %s"), *u_field->GetName()); - new_object->RemoveFunctionFromFunctionMap((UFunction *)u_field); + new_object->RemoveFunctionFromFunctionMap((UFunction*)u_field); FLinkerLoad::InvalidateExport(u_field); } u_field = u_field->Next; @@ -1633,14 +1633,14 @@ UClass *unreal_engine_new_uclass(char *name, UClass *outer_parent) -int unreal_engine_py_init(ue_PyUObject *, PyObject *, PyObject *); +int unreal_engine_py_init(ue_PyUObject*, PyObject*, PyObject*); void unreal_engine_init_py_module() { #if PY_MAJOR_VERSION >= 3 - PyObject *new_unreal_engine_module = PyImport_AddModule("unreal_engine"); + PyObject * new_unreal_engine_module = PyImport_AddModule("unreal_engine"); #else - PyObject *new_unreal_engine_module = Py_InitModule3("unreal_engine", NULL, unreal_engine_py_doc); + PyObject* new_unreal_engine_module = Py_InitModule3("unreal_engine", NULL, unreal_engine_py_doc); #endif ue_PyUObjectType.tp_new = PyType_GenericNew; ue_PyUObjectType.tp_init = (initproc)unreal_engine_py_init; @@ -1650,14 +1650,14 @@ void unreal_engine_init_py_module() return; Py_INCREF(&ue_PyUObjectType); - PyModule_AddObject(new_unreal_engine_module, "UObject", (PyObject *)&ue_PyUObjectType); + PyModule_AddObject(new_unreal_engine_module, "UObject", (PyObject*)& ue_PyUObjectType); - PyObject *unreal_engine_dict = PyModule_GetDict(new_unreal_engine_module); + PyObject* unreal_engine_dict = PyModule_GetDict(new_unreal_engine_module); - PyMethodDef *unreal_engine_function; + PyMethodDef* unreal_engine_function; for (unreal_engine_function = unreal_engine_methods; unreal_engine_function->ml_name != NULL; unreal_engine_function++) { - PyObject *func = PyCFunction_New(unreal_engine_function, NULL); + PyObject* func = PyCFunction_New(unreal_engine_function, NULL); PyDict_SetItemString(unreal_engine_dict, unreal_engine_function->ml_name, func); Py_DECREF(func); } @@ -1745,9 +1745,9 @@ void unreal_engine_init_py_module() ue_python_init_ivoice_capture(new_unreal_engine_module); - ue_py_register_magic_module((char *)"unreal_engine.classes", py_ue_new_uclassesimporter); - ue_py_register_magic_module((char *)"unreal_engine.enums", py_ue_new_enumsimporter); - ue_py_register_magic_module((char *)"unreal_engine.structs", py_ue_new_ustructsimporter); + ue_py_register_magic_module((char*)"unreal_engine.classes", py_ue_new_uclassesimporter); + ue_py_register_magic_module((char*)"unreal_engine.enums", py_ue_new_enumsimporter); + ue_py_register_magic_module((char*)"unreal_engine.structs", py_ue_new_ustructsimporter); PyDict_SetItemString(unreal_engine_dict, "ENGINE_MAJOR_VERSION", PyLong_FromLong(ENGINE_MAJOR_VERSION)); @@ -1851,18 +1851,18 @@ void unreal_engine_init_py_module() // utility functions -ue_PyUObject *ue_get_python_uobject(UObject *ue_obj) +ue_PyUObject* ue_get_python_uobject(UObject* ue_obj) { if (!ue_obj) return nullptr; - ue_PyUObject *ret = FUnrealEnginePythonHouseKeeper::Get()->GetPyUObject(ue_obj); + ue_PyUObject* ret = FUnrealEnginePythonHouseKeeper::Get()->GetPyUObject(ue_obj); if (!ret) { if (!ue_obj->IsValidLowLevel() || ue_obj->IsPendingKillOrUnreachable()) return nullptr; - ue_PyUObject *ue_py_object = (ue_PyUObject *)PyObject_New(ue_PyUObject, &ue_PyUObjectType); + ue_PyUObject* ue_py_object = (ue_PyUObject*)PyObject_New(ue_PyUObject, &ue_PyUObjectType); if (!ue_py_object) { return nullptr; @@ -1884,9 +1884,9 @@ ue_PyUObject *ue_get_python_uobject(UObject *ue_obj) } -ue_PyUObject *ue_get_python_uobject_inc(UObject *ue_obj) +ue_PyUObject* ue_get_python_uobject_inc(UObject* ue_obj) { - ue_PyUObject *ret = ue_get_python_uobject(ue_obj); + ue_PyUObject* ret = ue_get_python_uobject(ue_obj); if (ret) { Py_INCREF(ret); @@ -1896,9 +1896,9 @@ ue_PyUObject *ue_get_python_uobject_inc(UObject *ue_obj) void unreal_engine_py_log_error() { - PyObject *type = NULL; - PyObject *value = NULL; - PyObject *traceback = NULL; + PyObject* type = NULL; + PyObject* value = NULL; + PyObject* traceback = NULL; PyErr_Fetch(&type, &value, &traceback); PyErr_NormalizeException(&type, &value, &traceback); @@ -1909,9 +1909,9 @@ void unreal_engine_py_log_error() return; } - char *msg = NULL; + char* msg = NULL; #if PY_MAJOR_VERSION >= 3 - PyObject *zero = PyUnicode_AsUTF8String(PyObject_Str(value)); + PyObject * zero = PyUnicode_AsUTF8String(PyObject_Str(value)); if (zero) { msg = PyBytes_AsString(zero); @@ -1934,19 +1934,19 @@ void unreal_engine_py_log_error() return; } - PyObject *traceback_module = PyImport_ImportModule("traceback"); + PyObject* traceback_module = PyImport_ImportModule("traceback"); if (!traceback_module) { PyErr_Clear(); return; } - PyObject *traceback_dict = PyModule_GetDict(traceback_module); - PyObject *format_exception = PyDict_GetItemString(traceback_dict, "format_exception"); + PyObject* traceback_dict = PyModule_GetDict(traceback_module); + PyObject* format_exception = PyDict_GetItemString(traceback_dict, "format_exception"); if (format_exception) { - PyObject *ret = PyObject_CallFunctionObjArgs(format_exception, type, value, traceback, NULL); + PyObject* ret = PyObject_CallFunctionObjArgs(format_exception, type, value, traceback, NULL); if (!ret) { PyErr_Clear(); @@ -1956,7 +1956,7 @@ void unreal_engine_py_log_error() { for (int i = 0; i < PyList_Size(ret); i++) { - PyObject *item = PyList_GetItem(ret, i); + PyObject* item = PyList_GetItem(ret, i); if (item) { UE_LOG(LogPython, Error, TEXT("%s"), UTF8_TO_TCHAR(UEPyUnicode_AsUTF8(PyObject_Str(item)))); @@ -1973,23 +1973,23 @@ void unreal_engine_py_log_error() } // retrieve a UWorld from a generic UObject (if possible) -UWorld *ue_get_uworld(ue_PyUObject *py_obj) +UWorld* ue_get_uworld(ue_PyUObject* py_obj) { if (py_obj->ue_object->IsA()) { - return (UWorld *)py_obj->ue_object; + return (UWorld*)py_obj->ue_object; } if (py_obj->ue_object->IsA()) { - AActor *actor = (AActor *)py_obj->ue_object; + AActor* actor = (AActor*)py_obj->ue_object; return actor->GetWorld(); } if (py_obj->ue_object->IsA()) { - UActorComponent *component = (UActorComponent *)py_obj->ue_object; + UActorComponent* component = (UActorComponent*)py_obj->ue_object; return component->GetWorld(); } @@ -1997,23 +1997,23 @@ UWorld *ue_get_uworld(ue_PyUObject *py_obj) } // retrieve actor from component (if possible) -AActor *ue_get_actor(ue_PyUObject *py_obj) +AActor* ue_get_actor(ue_PyUObject* py_obj) { if (py_obj->ue_object->IsA()) { - return (AActor *)py_obj->ue_object; + return (AActor*)py_obj->ue_object; } if (py_obj->ue_object->IsA()) { - UActorComponent *tmp_component = (UActorComponent *)py_obj->ue_object; + UActorComponent* tmp_component = (UActorComponent*)py_obj->ue_object; return tmp_component->GetOwner(); } return nullptr; } // convert a property to a python object -PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) +PyObject* ue_py_convert_property(UProperty* prop, uint8* buffer, int32 index) { if (auto casted_prop = Cast(prop)) { @@ -2064,7 +2064,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) #if ENGINE_MINOR_VERSION >= 15 if (auto casted_prop = Cast(prop)) { - void *prop_addr = casted_prop->ContainerPtrToValuePtr(buffer, index); + void* prop_addr = casted_prop->ContainerPtrToValuePtr(buffer, index); uint64 enum_index = casted_prop->GetUnderlyingProperty()->GetUnsignedIntPropertyValue(prop_addr); return PyLong_FromUnsignedLong(enum_index); } @@ -2156,7 +2156,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) if (auto casted_prop = Cast(prop)) { auto value = casted_prop->GetPropertyValue_InContainer(buffer, index); - UObject *strong_obj = value.Get(); + UObject* strong_obj = value.Get(); if (strong_obj) { Py_RETURN_UOBJECT(strong_obj); @@ -2179,20 +2179,20 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) { FScriptArrayHelper_InContainer array_helper(casted_prop, buffer, index); - UProperty *array_prop = casted_prop->Inner; + UProperty* array_prop = casted_prop->Inner; // check for TArray, so we can use bytearray optimization if (auto uint8_tarray = Cast(array_prop)) { - uint8 *buf = array_helper.GetRawPtr(); - return PyByteArray_FromStringAndSize((char *)buf, array_helper.Num()); + uint8* buf = array_helper.GetRawPtr(); + return PyByteArray_FromStringAndSize((char*)buf, array_helper.Num()); } - PyObject *py_list = PyList_New(0); + PyObject* py_list = PyList_New(0); for (int i = 0; i < array_helper.Num(); i++) { - PyObject *item = ue_py_convert_property(array_prop, array_helper.GetRawPtr(i), 0); + PyObject* item = ue_py_convert_property(array_prop, array_helper.GetRawPtr(i), 0); if (!item) { Py_DECREF(py_list); @@ -2210,23 +2210,23 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) { FScriptMapHelper_InContainer map_helper(casted_prop, buffer, index); - PyObject *py_dict = PyDict_New(); + PyObject* py_dict = PyDict_New(); for (int32 i = 0; i < map_helper.Num(); i++) { if (map_helper.IsValidIndex(i)) { - uint8 *ptr = map_helper.GetPairPtr(i); + uint8* ptr = map_helper.GetPairPtr(i); - PyObject *py_key = ue_py_convert_property(map_helper.KeyProp, ptr, 0); + PyObject* py_key = ue_py_convert_property(map_helper.KeyProp, ptr, 0); if (!py_key) { Py_DECREF(py_dict); return NULL; } - PyObject *py_value = ue_py_convert_property(map_helper.ValueProp, ptr, 0); + PyObject* py_value = ue_py_convert_property(map_helper.ValueProp, ptr, 0); if (!py_value) { Py_DECREF(py_dict); @@ -2247,7 +2247,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer, int32 index) } // convert a python object to a property -bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, int32 index) +bool ue_py_convert_pyobject(PyObject* py_obj, UProperty* prop, uint8* buffer, int32 index) { if (PyBool_Check(py_obj)) @@ -2270,42 +2270,42 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); + PyObject* py_long = PyNumber_Long(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyLong_AsLong(py_long), index); Py_DECREF(py_long); return true; } if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); + PyObject* py_long = PyNumber_Long(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyLong_AsUnsignedLong(py_long), index); Py_DECREF(py_long); return true; } if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); + PyObject* py_long = PyNumber_Long(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyLong_AsLongLong(py_long), index); Py_DECREF(py_long); return true; } if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); + PyObject* py_long = PyNumber_Long(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyLong_AsUnsignedLongLong(py_long), index); Py_DECREF(py_long); return true; } if (auto casted_prop = Cast(prop)) { - PyObject *py_float = PyNumber_Float(py_obj); + PyObject* py_float = PyNumber_Float(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyFloat_AsDouble(py_float), index); Py_DECREF(py_float); return true; } if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); + PyObject* py_long = PyNumber_Long(py_obj); casted_prop->SetPropertyValue_InContainer(buffer, PyLong_AsUnsignedLong(py_long), index); Py_DECREF(py_long); return true; @@ -2313,8 +2313,8 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in #if ENGINE_MINOR_VERSION >= 15 if (auto casted_prop = Cast(prop)) { - PyObject *py_long = PyNumber_Long(py_obj); - void *prop_addr = casted_prop->ContainerPtrToValuePtr(buffer, index); + PyObject* py_long = PyNumber_Long(py_obj); + void* prop_addr = casted_prop->ContainerPtrToValuePtr(buffer, index); casted_prop->GetUnderlyingProperty()->SetIntPropertyValue(prop_addr, (uint64)PyLong_AsUnsignedLong(py_long)); Py_DECREF(py_long); return true; @@ -2355,7 +2355,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { Py_ssize_t pybytes_len = PyBytes_Size(py_obj); - uint8 *buf = (uint8 *)PyBytes_AsString(py_obj); + uint8* buf = (uint8*)PyBytes_AsString(py_obj); // fix array helper size @@ -2387,7 +2387,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { Py_ssize_t pybytes_len = PyByteArray_Size(py_obj); - uint8 *buf = (uint8 *)PyByteArray_AsString(py_obj); + uint8* buf = (uint8*)PyByteArray_AsString(py_obj); // fix array helper size @@ -2416,7 +2416,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { FScriptArrayHelper_InContainer helper(casted_prop, buffer, index); - UProperty *array_prop = casted_prop->Inner; + UProperty* array_prop = casted_prop->Inner; Py_ssize_t pylist_len = PyList_Size(py_obj); // fix array helper size @@ -2431,7 +2431,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in for (int i = 0; i < (int)pylist_len; i++) { - PyObject *py_item = PyList_GetItem(py_obj, i); + PyObject* py_item = PyList_GetItem(py_obj, i); if (!ue_py_convert_pyobject(py_item, array_prop, helper.GetRawPtr(i), 0)) { return false; @@ -2449,7 +2449,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { FScriptArrayHelper_InContainer helper(casted_prop, buffer, index); - UProperty *array_prop = casted_prop->Inner; + UProperty* array_prop = casted_prop->Inner; Py_ssize_t pytuple_len = PyTuple_Size(py_obj); // fix array helper size @@ -2464,7 +2464,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in for (int i = 0; i < (int)pytuple_len; i++) { - PyObject *py_item = PyTuple_GetItem(py_obj, i); + PyObject* py_item = PyTuple_GetItem(py_obj, i); if (!ue_py_convert_pyobject(py_item, array_prop, helper.GetRawPtr(i), 0)) { return false; @@ -2483,8 +2483,8 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { FScriptMapHelper_InContainer map_helper(casted_prop, buffer, index); - PyObject *py_key = nullptr; - PyObject *py_value = nullptr; + PyObject* py_key = nullptr; + PyObject* py_value = nullptr; Py_ssize_t pos = 0; map_helper.EmptyValues(); @@ -2492,7 +2492,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in { int32 hindex = map_helper.AddDefaultValue_Invalid_NeedsRehash(); - uint8 *ptr = map_helper.GetPairPtr(hindex); + uint8* ptr = map_helper.GetPairPtr(hindex); if (!ue_py_convert_pyobject(py_key, casted_prop->KeyProp, ptr, 0)) { @@ -2515,7 +2515,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in // structs - if (ue_PyFVector *py_vec = py_ue_is_fvector(py_obj)) + if (ue_PyFVector * py_vec = py_ue_is_fvector(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2528,7 +2528,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFVector2D *py_vec = py_ue_is_fvector2d(py_obj)) + if (ue_PyFVector2D * py_vec = py_ue_is_fvector2d(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2541,7 +2541,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFRotator *py_rot = py_ue_is_frotator(py_obj)) + if (ue_PyFRotator * py_rot = py_ue_is_frotator(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2554,7 +2554,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFTransform *py_transform = py_ue_is_ftransform(py_obj)) + if (ue_PyFTransform * py_transform = py_ue_is_ftransform(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2567,7 +2567,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFColor *py_color = py_ue_is_fcolor(py_obj)) + if (ue_PyFColor * py_color = py_ue_is_fcolor(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2581,7 +2581,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFLinearColor *py_color = py_ue_is_flinearcolor(py_obj)) + if (ue_PyFLinearColor * py_color = py_ue_is_flinearcolor(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2594,7 +2594,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (ue_PyFHitResult *py_hit = py_ue_is_fhitresult(py_obj)) + if (ue_PyFHitResult * py_hit = py_ue_is_fhitresult(py_obj)) { if (auto casted_prop = Cast(prop)) { @@ -2610,12 +2610,12 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in // generic structs if (py_ue_is_uscriptstruct(py_obj)) { - ue_PyUScriptStruct *py_u_struct = (ue_PyUScriptStruct *)py_obj; + ue_PyUScriptStruct* py_u_struct = (ue_PyUScriptStruct*)py_obj; if (auto casted_prop = Cast(prop)) { if (casted_prop->Struct == py_u_struct->u_struct) { - uint8 *dest = casted_prop->ContainerPtrToValuePtr(buffer, index); + uint8* dest = casted_prop->ContainerPtrToValuePtr(buffer, index); py_u_struct->u_struct->InitializeStruct(dest); py_u_struct->u_struct->CopyScriptStruct(dest, py_u_struct->u_struct_ptr); return true; @@ -2624,9 +2624,9 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in return false; } - if (PyObject_IsInstance(py_obj, (PyObject *)&ue_PyUObjectType)) + if (PyObject_IsInstance(py_obj, (PyObject*)& ue_PyUObjectType)) { - ue_PyUObject *ue_obj = (ue_PyUObject *)py_obj; + ue_PyUObject* ue_obj = (ue_PyUObject*)py_obj; if (ue_obj->ue_object->IsA()) { if (auto casted_prop = Cast(prop)) @@ -2739,24 +2739,24 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer, in // check if a python object is a wrapper to a UObject -ue_PyUObject *ue_is_pyuobject(PyObject *obj) +ue_PyUObject* ue_is_pyuobject(PyObject* obj) { - if (!PyObject_IsInstance(obj, (PyObject *)&ue_PyUObjectType)) + if (!PyObject_IsInstance(obj, (PyObject*)& ue_PyUObjectType)) return nullptr; - return (ue_PyUObject *)obj; + return (ue_PyUObject*)obj; } -void ue_bind_events_for_py_class_by_attribute(UObject *u_obj, PyObject *py_class) +void ue_bind_events_for_py_class_by_attribute(UObject* u_obj, PyObject* py_class) { // attempt to register events - PyObject *attrs = PyObject_Dir(py_class); + PyObject* attrs = PyObject_Dir(py_class); if (!attrs) return; - AActor *actor = Cast(u_obj); + AActor* actor = Cast(u_obj); if (!actor) { - UActorComponent *component = Cast(u_obj); + UActorComponent* component = Cast(u_obj); if (!component) return; actor = component->GetOwner(); @@ -2765,14 +2765,14 @@ void ue_bind_events_for_py_class_by_attribute(UObject *u_obj, PyObject *py_class Py_ssize_t len = PyList_Size(attrs); for (Py_ssize_t i = 0; i < len; i++) { - PyObject *py_attr_name = PyList_GetItem(attrs, i); + PyObject* py_attr_name = PyList_GetItem(attrs, i); if (!py_attr_name || !PyUnicodeOrString_Check(py_attr_name)) continue; - PyObject *item = PyObject_GetAttrString(py_class, UEPyUnicode_AsUTF8(py_attr_name)); + PyObject* item = PyObject_GetAttrString(py_class, UEPyUnicode_AsUTF8(py_attr_name)); if (item && PyCallable_Check(item)) { // check for ue_event signature - PyObject *event_signature = PyObject_GetAttrString(item, (char*)"ue_event"); + PyObject* event_signature = PyObject_GetAttrString(item, (char*)"ue_event"); if (event_signature) { if (PyUnicodeOrString_Check(event_signature)) @@ -2797,7 +2797,7 @@ void ue_bind_events_for_py_class_by_attribute(UObject *u_obj, PyObject *py_class else { bool found = false; - for (UActorComponent *component : actor->GetComponents()) + for (UActorComponent* component : actor->GetComponents()) { if (component->GetFName() == FName(*parts[0])) { @@ -2834,23 +2834,23 @@ void ue_bind_events_for_py_class_by_attribute(UObject *u_obj, PyObject *py_class } // automatically bind events based on class methods names -void ue_autobind_events_for_pyclass(ue_PyUObject *u_obj, PyObject *py_class) +void ue_autobind_events_for_pyclass(ue_PyUObject* u_obj, PyObject* py_class) { - PyObject *attrs = PyObject_Dir(py_class); + PyObject* attrs = PyObject_Dir(py_class); if (!attrs) return; Py_ssize_t len = PyList_Size(attrs); for (Py_ssize_t i = 0; i < len; i++) { - PyObject *py_attr_name = PyList_GetItem(attrs, i); + PyObject* py_attr_name = PyList_GetItem(attrs, i); if (!py_attr_name || !PyUnicodeOrString_Check(py_attr_name)) continue; FString attr_name = UTF8_TO_TCHAR(UEPyUnicode_AsUTF8(py_attr_name)); if (!attr_name.StartsWith("on_", ESearchCase::CaseSensitive)) continue; // check if the attr is a callable - PyObject *item = PyObject_GetAttrString(py_class, TCHAR_TO_UTF8(*attr_name)); + PyObject* item = PyObject_GetAttrString(py_class, TCHAR_TO_UTF8(*attr_name)); if (item && PyCallable_Check(item)) { TArray parts; @@ -2874,24 +2874,24 @@ void ue_autobind_events_for_pyclass(ue_PyUObject *u_obj, PyObject *py_class) Py_DECREF(attrs); } -static void py_ue_destroy_params(UFunction *u_function, uint8 *buffer) +static void py_ue_destroy_params(UFunction* u_function, uint8* buffer) { // destroy params TFieldIterator DArgs(u_function); for (; DArgs && (DArgs->PropertyFlags & CPF_Parm); ++DArgs) { - UProperty *prop = *DArgs; + UProperty* prop = *DArgs; prop->DestroyValue_InContainer(buffer); } } -PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject *args, int argn, PyObject *kwargs) +PyObject* py_ue_ufunction_call(UFunction* u_function, UObject* u_obj, PyObject* args, int argn, PyObject* kwargs) { // check for __super call if (kwargs) { - PyObject *is_super_call = PyDict_GetItemString(kwargs, (char *)"__super"); + PyObject* is_super_call = PyDict_GetItemString(kwargs, (char*)"__super"); if (is_super_call) { if (!u_function->GetSuperFunction()) @@ -2903,12 +2903,12 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * } //NOTE: u_function->PropertiesSize maps to local variable uproperties + ufunction paramaters uproperties - uint8 *buffer = (uint8 *)FMemory_Alloca(u_function->ParmsSize); + uint8* buffer = (uint8*)FMemory_Alloca(u_function->ParmsSize); FMemory::Memzero(buffer, u_function->ParmsSize); // initialize args for (TFieldIterator IArgs(u_function); IArgs && IArgs->HasAnyPropertyFlags(CPF_Parm); ++IArgs) { - UProperty *prop = *IArgs; + UProperty* prop = *IArgs; if (!prop->HasAnyPropertyFlags(CPF_ZeroConstructor)) { prop->InitializeValue_InContainer(buffer); @@ -2944,10 +2944,10 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * TFieldIterator PArgs(u_function); for (; PArgs && ((PArgs->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm); ++PArgs) { - UProperty *prop = *PArgs; + UProperty* prop = *PArgs; if (argn < tuple_len) { - PyObject *py_arg = PyTuple_GetItem(args, argn); + PyObject* py_arg = PyTuple_GetItem(args, argn); if (!py_arg) { py_ue_destroy_params(u_function, buffer); @@ -2961,8 +2961,8 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * } else if (kwargs) { - char *prop_name = TCHAR_TO_UTF8(*prop->GetName()); - PyObject *dict_value = PyDict_GetItemString(kwargs, prop_name); + char* prop_name = TCHAR_TO_UTF8(*prop->GetName()); + PyObject* dict_value = PyDict_GetItemString(kwargs, prop_name); if (dict_value) { if (!ue_py_convert_pyobject(dict_value, prop, buffer, 0)) @@ -2986,13 +2986,13 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * u_obj->ProcessEvent(u_function, buffer); Py_END_ALLOW_THREADS; - PyObject *ret = nullptr; + PyObject* ret = nullptr; int has_ret_param = 0; TFieldIterator Props(u_function); for (; Props; ++Props) { - UProperty *prop = *Props; + UProperty* prop = *Props; if (prop->GetPropertyFlags() & CPF_ReturnParm) { ret = ue_py_convert_property(prop, buffer, 0); @@ -3009,7 +3009,7 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * if (has_out_params > 0) { - PyObject *multi_ret = PyTuple_New(has_out_params + has_ret_param); + PyObject* multi_ret = PyTuple_New(has_out_params + has_ret_param); if (ret) { PyTuple_SetItem(multi_ret, 0, ret); @@ -3017,13 +3017,13 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * TFieldIterator OProps(u_function); for (; OProps; ++OProps) { - UProperty *prop = *OProps; + UProperty* prop = *OProps; if (prop->HasAnyPropertyFlags(CPF_OutParm) && (prop->IsA() || prop->HasAnyPropertyFlags(CPF_ConstParm) == false)) { // skip return param as it must be always the first if (prop->GetPropertyFlags() & CPF_ReturnParm) continue; - PyObject *py_out = ue_py_convert_property(prop, buffer, 0); + PyObject* py_out = ue_py_convert_property(prop, buffer, 0); if (!py_out) { Py_DECREF(multi_ret); @@ -3049,9 +3049,9 @@ PyObject *py_ue_ufunction_call(UFunction *u_function, UObject *u_obj, PyObject * Py_RETURN_NONE; } -PyObject *ue_unbind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_callable, bool fail_on_wrong_property) +PyObject* ue_unbind_pyevent(ue_PyUObject* u_obj, FString event_name, PyObject* py_callable, bool fail_on_wrong_property) { - UProperty *u_property = u_obj->ue_object->GetClass()->FindPropertyByName(FName(*event_name)); + UProperty* u_property = u_obj->ue_object->GetClass()->FindPropertyByName(FName(*event_name)); if (!u_property) { if (fail_on_wrong_property) @@ -3061,20 +3061,29 @@ PyObject *ue_unbind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *p if (auto casted_prop = Cast(u_property)) { - UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->FindDelegate(u_obj->ue_object, py_callable); - if (py_delegate != nullptr) - { - FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object); - multiscript_delegate.Remove(py_delegate, FName("PyFakeCallable")); + UPythonDelegate* py_delegate = FUnrealEnginePythonHouseKeeper::Get()->FindDelegate(u_obj->ue_object, py_callable); + if (py_delegate != nullptr) + { +#if ENGINE_MINOR_VERSION < 23 + FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object); +#else + FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(u_obj->ue_object); +#endif - // re-assign multicast delegate - casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, multiscript_delegate); - } + multiscript_delegate.Remove(py_delegate, FName("PyFakeCallable")); + + // re-assign multicast delegate +#if ENGINE_MINOR_VERSION < 23 + casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, multiscript_delegate); +#else + casted_prop->SetMulticastDelegate(u_obj->ue_object, multiscript_delegate); +#endif + } } else if (auto casted_prop_delegate = Cast(u_property)) { FScriptDelegate script_delegate = casted_prop_delegate->GetPropertyValue_InContainer(u_obj->ue_object); - script_delegate.Unbind(); + script_delegate.Unbind(); // re-assign multicast delegate casted_prop_delegate->SetPropertyValue_InContainer(u_obj->ue_object, script_delegate); @@ -3088,10 +3097,10 @@ PyObject *ue_unbind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *p Py_RETURN_NONE; } -PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_callable, bool fail_on_wrong_property) +PyObject* ue_bind_pyevent(ue_PyUObject* u_obj, FString event_name, PyObject* py_callable, bool fail_on_wrong_property) { - UProperty *u_property = u_obj->ue_object->GetClass()->FindPropertyByName(FName(*event_name)); + UProperty* u_property = u_obj->ue_object->GetClass()->FindPropertyByName(FName(*event_name)); if (!u_property) { if (fail_on_wrong_property) @@ -3101,10 +3110,14 @@ PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_ if (auto casted_prop = Cast(u_property)) { +#if ENGINE_MINOR_VERSION < 23 FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object); +#else + FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(u_obj->ue_object); +#endif FScriptDelegate script_delegate; - UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop->SignatureFunction); + UPythonDelegate* py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop->SignatureFunction); // fake UFUNCTION for bypassing checks script_delegate.BindUFunction(py_delegate, FName("PyFakeCallable")); @@ -3112,13 +3125,17 @@ PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_ multiscript_delegate.Add(script_delegate); // re-assign multicast delegate +#if ENGINE_MINOR_VERSION < 23 casted_prop->SetPropertyValue_InContainer(u_obj->ue_object, multiscript_delegate); +#else + casted_prop->SetMulticastDelegate(u_obj->ue_object, multiscript_delegate); +#endif } else if (auto casted_prop_delegate = Cast(u_property)) { FScriptDelegate script_delegate = casted_prop_delegate->GetPropertyValue_InContainer(u_obj->ue_object); - UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop_delegate->SignatureFunction); + UPythonDelegate* py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop_delegate->SignatureFunction); // fake UFUNCTION for bypassing checks script_delegate.BindUFunction(py_delegate, FName("PyFakeCallable")); @@ -3134,10 +3151,10 @@ PyObject *ue_bind_pyevent(ue_PyUObject *u_obj, FString event_name, PyObject *py_ Py_RETURN_NONE; } -UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_callable, uint32 function_flags) +UFunction* unreal_engine_add_function(UClass* u_class, char* name, PyObject* py_callable, uint32 function_flags) { - UFunction *parent_function = u_class->GetSuperClass()->FindFunctionByName(UTF8_TO_TCHAR(name)); + UFunction* parent_function = u_class->GetSuperClass()->FindFunctionByName(UTF8_TO_TCHAR(name)); // if the function is not available in the parent // check for name collision if (!parent_function) @@ -3149,7 +3166,7 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ } } - UPythonFunction *function = NewObject(u_class, UTF8_TO_TCHAR(name), RF_Public | RF_Transient | RF_MarkAsNative); + UPythonFunction* function = NewObject(u_class, UTF8_TO_TCHAR(name), RF_Public | RF_Transient | RF_MarkAsNative); function->SetPyCallable(py_callable); #if ENGINE_MINOR_VERSION < 18 @@ -3167,34 +3184,34 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ // iterate all arguments using inspect.signature() // this is required to maintaining args order - PyObject *inspect = PyImport_ImportModule("inspect"); + PyObject* inspect = PyImport_ImportModule("inspect"); if (!inspect) { return NULL; } - PyObject *signature = PyObject_CallMethod(inspect, (char *)"signature", (char *)"O", py_callable); + PyObject* signature = PyObject_CallMethod(inspect, (char*)"signature", (char*)"O", py_callable); if (!signature) { return NULL; } - PyObject *parameters = PyObject_GetAttrString(signature, "parameters"); + PyObject* parameters = PyObject_GetAttrString(signature, "parameters"); if (!parameters) { return NULL; } - PyObject *annotations = PyObject_GetAttrString(py_callable, "__annotations__"); + PyObject* annotations = PyObject_GetAttrString(py_callable, "__annotations__"); - UField **next_property = &function->Children; - UProperty **next_property_link = &function->PropertyLink; + UField** next_property = &function->Children; + UProperty** next_property_link = &function->PropertyLink; - PyObject *parameters_keys = PyObject_GetIter(parameters); + PyObject* parameters_keys = PyObject_GetIter(parameters); // do not process args if no annotations are available while (annotations) { - PyObject *key = PyIter_Next(parameters_keys); + PyObject* key = PyIter_Next(parameters_keys); if (!key) { if (PyErr_Occurred()) @@ -3204,79 +3221,79 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ if (!PyUnicodeOrString_Check(key)) continue; - const char *p_name = UEPyUnicode_AsUTF8(key); + const char* p_name = UEPyUnicode_AsUTF8(key); - PyObject *value = PyDict_GetItem(annotations, key); + PyObject* value = PyDict_GetItem(annotations, key); if (!value) continue; - UProperty *prop = nullptr; + UProperty* prop = nullptr; if (PyType_Check(value)) { - if ((PyTypeObject *)value == &PyFloat_Type) + if ((PyTypeObject*)value == &PyFloat_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)value == &PyUnicode_Type) + else if ((PyTypeObject*)value == &PyUnicode_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)value == &PyBool_Type) + else if ((PyTypeObject*)value == &PyBool_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)value == &PyLong_Type) + else if ((PyTypeObject*)value == &PyLong_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)value == &ue_PyFVectorType) + else if ((PyTypeObject*)value == &ue_PyFVectorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)value == &ue_PyFVector2DType) + else if ((PyTypeObject*)value == &ue_PyFVector2DType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)value == &ue_PyFRotatorType) + else if ((PyTypeObject*)value == &ue_PyFRotatorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)value == &ue_PyFLinearColorType) + else if ((PyTypeObject*)value == &ue_PyFLinearColorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)value == &ue_PyFColorType) + else if ((PyTypeObject*)value == &ue_PyFColorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)value == &ue_PyFTransformType) + else if ((PyTypeObject*)value == &ue_PyFTransformType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } #if ENGINE_MINOR_VERSION > 18 - else if ((PyTypeObject *)value == &ue_PyFQuatType) + else if ((PyTypeObject*)value == &ue_PyFQuatType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } #endif - else if (PyObject_IsInstance(value, (PyObject *)&PyType_Type)) + else if (PyObject_IsInstance(value, (PyObject*)& PyType_Type)) { // Method annotation like foo:typing.Type[Pawn] produces annotations like typing.Type[Pawn], with .__args__ = (Pawn,) - PyObject *type_args = PyObject_GetAttrString(value, "__args__"); + PyObject* type_args = PyObject_GetAttrString(value, "__args__"); if (!type_args) { UE_LOG(LogPython, Error, TEXT("missing type info on %s"), UTF8_TO_TCHAR(name)); @@ -3288,8 +3305,8 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ UE_LOG(LogPython, Error, TEXT("exactly one class is allowed in type info for %s"), UTF8_TO_TCHAR(name)); return nullptr; } - PyObject *py_class = PyTuple_GetItem(type_args, 0); - ue_PyUObject *py_obj = ue_is_pyuobject(py_class); + PyObject* py_class = PyTuple_GetItem(type_args, 0); + ue_PyUObject* py_obj = ue_is_pyuobject(py_class); if (!py_obj) { Py_DECREF(type_args); @@ -3302,27 +3319,27 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ UE_LOG(LogPython, Error, TEXT("type for %s must be a UClass"), UTF8_TO_TCHAR(name)); return nullptr; } - UClassProperty *prop_class = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UClassProperty* prop_class = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_class->SetMetaClass((UClass*)py_obj->ue_object); prop_class->PropertyClass = UClass::StaticClass(); prop = prop_class; Py_DECREF(type_args); } } - else if (ue_PyUObject *py_obj = ue_is_pyuobject(value)) + else if (ue_PyUObject * py_obj = ue_is_pyuobject(value)) { if (py_obj->ue_object->IsA()) { - UClass *p_u_class = (UClass *)py_obj->ue_object; - UObjectProperty *prop_base = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UClass* p_u_class = (UClass*)py_obj->ue_object; + UObjectProperty* prop_base = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_base->SetPropertyClass(p_u_class); prop = prop_base; } #if ENGINE_MINOR_VERSION > 17 else if (py_obj->ue_object->IsA()) { - UEnumProperty *prop_enum = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); - UNumericProperty *prop_underlying = NewObject(prop_enum, TEXT("UnderlyingType"), RF_Public); + UEnumProperty* prop_enum = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UNumericProperty* prop_underlying = NewObject(prop_enum, TEXT("UnderlyingType"), RF_Public); prop_enum->SetEnum((UEnum*)py_obj->ue_object); prop_enum->AddCppProperty(prop_underlying); prop = prop_enum; @@ -3330,7 +3347,7 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ #endif else if (py_obj->ue_object->IsA()) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = (UScriptStruct*)py_obj->ue_object; prop = prop_struct; } @@ -3354,78 +3371,78 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ // check for return value if (annotations) { - PyObject *py_return_value = PyDict_GetItemString(annotations, "return"); + PyObject* py_return_value = PyDict_GetItemString(annotations, "return"); if (py_return_value) { UE_LOG(LogPython, Warning, TEXT("Return Value found")); - UProperty *prop = nullptr; - char *p_name = (char *) "ReturnValue"; + UProperty* prop = nullptr; + char* p_name = (char*) "ReturnValue"; if (PyType_Check(py_return_value)) { - if ((PyTypeObject *)py_return_value == &PyFloat_Type) + if ((PyTypeObject*)py_return_value == &PyFloat_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)py_return_value == &PyUnicode_Type) + else if ((PyTypeObject*)py_return_value == &PyUnicode_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)py_return_value == &PyBool_Type) + else if ((PyTypeObject*)py_return_value == &PyBool_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)py_return_value == &PyLong_Type) + else if ((PyTypeObject*)py_return_value == &PyLong_Type) { prop = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); } - else if ((PyTypeObject *)py_return_value == &ue_PyFVectorType) + else if ((PyTypeObject*)py_return_value == &ue_PyFVectorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)py_return_value == &ue_PyFVector2DType) + else if ((PyTypeObject*)py_return_value == &ue_PyFVector2DType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)py_return_value == &ue_PyFRotatorType) + else if ((PyTypeObject*)py_return_value == &ue_PyFRotatorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)py_return_value == &ue_PyFLinearColorType) + else if ((PyTypeObject*)py_return_value == &ue_PyFLinearColorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)py_return_value == &ue_PyFColorType) + else if ((PyTypeObject*)py_return_value == &ue_PyFColorType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } - else if ((PyTypeObject *)py_return_value == &ue_PyFTransformType) + else if ((PyTypeObject*)py_return_value == &ue_PyFTransformType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } #if ENGINE_MINOR_VERSION > 18 - else if ((PyTypeObject *)py_return_value == &ue_PyFQuatType) + else if ((PyTypeObject*)py_return_value == &ue_PyFQuatType) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = TBaseStructure::Get(); prop = prop_struct; } #endif - else if (PyObject_IsInstance(py_return_value, (PyObject *)&PyType_Type)) + else if (PyObject_IsInstance(py_return_value, (PyObject*)& PyType_Type)) { // Method annotation like foo:typing.Type[Pawn] produces annotations like typing.Type[Pawn], with .__args__ = (Pawn,) - PyObject *type_args = PyObject_GetAttrString(py_return_value, "__args__"); + PyObject* type_args = PyObject_GetAttrString(py_return_value, "__args__"); if (!type_args) { UE_LOG(LogPython, Error, TEXT("missing type info on %s"), UTF8_TO_TCHAR(name)); @@ -3437,8 +3454,8 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ UE_LOG(LogPython, Error, TEXT("exactly one class is allowed in type info for %s"), UTF8_TO_TCHAR(name)); return nullptr; } - PyObject *py_class = PyTuple_GetItem(type_args, 0); - ue_PyUObject *py_obj = ue_is_pyuobject(py_class); + PyObject* py_class = PyTuple_GetItem(type_args, 0); + ue_PyUObject* py_obj = ue_is_pyuobject(py_class); if (!py_obj) { Py_DECREF(type_args); @@ -3451,27 +3468,27 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ UE_LOG(LogPython, Error, TEXT("type for %s must be a UClass"), UTF8_TO_TCHAR(name)); return nullptr; } - UClassProperty *prop_class = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UClassProperty* prop_class = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_class->SetMetaClass((UClass*)py_obj->ue_object); prop_class->PropertyClass = UClass::StaticClass(); prop = prop_class; Py_DECREF(type_args); } } - else if (ue_PyUObject *py_obj = ue_is_pyuobject(py_return_value)) + else if (ue_PyUObject * py_obj = ue_is_pyuobject(py_return_value)) { if (py_obj->ue_object->IsA()) { - UClass *p_u_class = (UClass *)py_obj->ue_object; - UObjectProperty *prop_base = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UClass* p_u_class = (UClass*)py_obj->ue_object; + UObjectProperty* prop_base = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_base->SetPropertyClass(p_u_class); prop = prop_base; } #if ENGINE_MINOR_VERSION > 17 else if (py_obj->ue_object->IsA()) { - UEnumProperty *prop_enum = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); - UNumericProperty *prop_underlying = NewObject(prop_enum, TEXT("UnderlyingType"), RF_Public); + UEnumProperty* prop_enum = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UNumericProperty* prop_underlying = NewObject(prop_enum, TEXT("UnderlyingType"), RF_Public); prop_enum->SetEnum((UEnum*)py_obj->ue_object); prop_enum->AddCppProperty(prop_underlying); prop = prop_enum; @@ -3479,7 +3496,7 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ #endif else if (py_obj->ue_object->IsA()) { - UStructProperty *prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); + UStructProperty* prop_struct = NewObject(function, UTF8_TO_TCHAR(p_name), RF_Public); prop_struct->Struct = (UScriptStruct*)py_obj->ue_object; prop = prop_struct; } @@ -3512,11 +3529,11 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ TFieldIterator It(parent_function); while (It) { - UProperty *p = *It; + UProperty* p = *It; if (p->PropertyFlags & CPF_Parm) { UE_LOG(LogPython, Warning, TEXT("Parent PROP: %s %d/%d %d %d %d %s %p"), *p->GetName(), (int)p->PropertyFlags, (int)UFunction::GetDefaultIgnoredSignatureCompatibilityFlags(), (int)(p->PropertyFlags & ~UFunction::GetDefaultIgnoredSignatureCompatibilityFlags()), p->GetSize(), p->GetOffset_ForGC(), *p->GetClass()->GetName(), p->GetClass()); - UClassProperty *ucp = Cast(p); + UClassProperty* ucp = Cast(p); if (ucp) { UE_LOG(LogPython, Warning, TEXT("Parent UClassProperty = %p %s %p %s"), ucp->PropertyClass, *ucp->PropertyClass->GetName(), ucp->MetaClass, *ucp->MetaClass->GetName()); @@ -3528,11 +3545,11 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ TFieldIterator It2(function); while (It2) { - UProperty *p = *It2; + UProperty* p = *It2; if (p->PropertyFlags & CPF_Parm) { UE_LOG(LogPython, Warning, TEXT("Function PROP: %s %d/%d %d %d %d %s %p"), *p->GetName(), (int)p->PropertyFlags, (int)UFunction::GetDefaultIgnoredSignatureCompatibilityFlags(), (int)(p->PropertyFlags & ~UFunction::GetDefaultIgnoredSignatureCompatibilityFlags()), p->GetSize(), p->GetOffset_ForGC(), *p->GetClass()->GetName(), p->GetClass()); - UClassProperty *ucp = Cast(p); + UClassProperty* ucp = Cast(p); if (ucp) { UE_LOG(LogPython, Warning, TEXT("Function UClassProperty = %p %s %p %s"), ucp->PropertyClass, *ucp->PropertyClass->GetName(), ucp->MetaClass, *ucp->MetaClass->GetName()); @@ -3552,7 +3569,7 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ TFieldIterator props(function, EFieldIteratorFlags::ExcludeSuper); for (; props; ++props) { - UProperty *p = *props; + UProperty* p = *props; if (p->HasAnyPropertyFlags(CPF_Parm)) { function->NumParms++; @@ -3581,9 +3598,9 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ #endif #if ENGINE_MINOR_VERSION > 18 - function->SetNativeFunc((FNativeFuncPtr)&UPythonFunction::CallPythonCallable); + function->SetNativeFunc((FNativeFuncPtr)& UPythonFunction::CallPythonCallable); #else - function->SetNativeFunc((Native)&UPythonFunction::CallPythonCallable); + function->SetNativeFunc((Native)& UPythonFunction::CallPythonCallable); #endif function->Next = u_class->Children; @@ -3626,24 +3643,24 @@ UFunction *unreal_engine_add_function(UClass *u_class, char *name, PyObject *py_ return function; } -FGuid *ue_py_check_fguid(PyObject *py_obj) +FGuid* ue_py_check_fguid(PyObject* py_obj) { - ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_obj); + ue_PyUScriptStruct* ue_py_struct = py_ue_is_uscriptstruct(py_obj); if (!ue_py_struct) { return nullptr; } - if (ue_py_struct->u_struct == FindObject(ANY_PACKAGE, UTF8_TO_TCHAR((char *)"Guid"))) + if (ue_py_struct->u_struct == FindObject(ANY_PACKAGE, UTF8_TO_TCHAR((char*)"Guid"))) { return (FGuid*)ue_py_struct->u_struct_ptr; } return nullptr; } -uint8 * do_ue_py_check_struct(PyObject *py_obj, UScriptStruct* chk_u_struct) +uint8* do_ue_py_check_struct(PyObject* py_obj, UScriptStruct* chk_u_struct) { - ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_obj); + ue_PyUScriptStruct* ue_py_struct = py_ue_is_uscriptstruct(py_obj); if (!ue_py_struct) { return nullptr; @@ -3657,9 +3674,9 @@ uint8 * do_ue_py_check_struct(PyObject *py_obj, UScriptStruct* chk_u_struct) return nullptr; } -bool do_ue_py_check_childstruct(PyObject *py_obj, UScriptStruct* parent_u_struct) +bool do_ue_py_check_childstruct(PyObject* py_obj, UScriptStruct* parent_u_struct) { - ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_obj); + ue_PyUScriptStruct* ue_py_struct = py_ue_is_uscriptstruct(py_obj); if (!ue_py_struct) { return false; @@ -3671,10 +3688,10 @@ bool do_ue_py_check_childstruct(PyObject *py_obj, UScriptStruct* parent_u_struct #if PY_MAJOR_VERSION >= 3 -static PyObject *init_unreal_engine() +static PyObject * init_unreal_engine() { - PyObject *new_unreal_engine_module = PyModule_Create(&unreal_engine_module); + PyObject* new_unreal_engine_module = PyModule_Create(&unreal_engine_module); if (!new_unreal_engine_module) return nullptr; diff --git a/Source/UnrealEnginePython/Private/UEPySubclassing.cpp b/Source/UnrealEnginePython/Private/UEPySubclassing.cpp index 870a62474..548a83935 100644 --- a/Source/UnrealEnginePython/Private/UEPySubclassing.cpp +++ b/Source/UnrealEnginePython/Private/UEPySubclassing.cpp @@ -346,7 +346,12 @@ int unreal_engine_py_init(ue_PyUObject *self, PyObject *args, PyObject *kwds) { if (auto casted_prop = Cast(u_property)) { +#if ENGINE_MINOR_VERSION >= 23 + FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(ObjectInitializer.GetObj()); +#else + FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(ObjectInitializer.GetObj()); +#endif FScriptDelegate script_delegate; UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(ObjectInitializer.GetObj(), mc_value, casted_prop->SignatureFunction); @@ -357,7 +362,11 @@ int unreal_engine_py_init(ue_PyUObject *self, PyObject *args, PyObject *kwds) multiscript_delegate.Add(script_delegate); // re-assign multicast delegate +#if ENGINE_MINOR_VERSION >= 23 + casted_prop->SetMulticastDelegate(ObjectInitializer.GetObj(), multiscript_delegate); +#else casted_prop->SetPropertyValue_InContainer(ObjectInitializer.GetObj(), multiscript_delegate); +#endif } else { diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyAnimSequence.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyAnimSequence.cpp index 7eafe7b51..2674c0d1b 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyAnimSequence.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyAnimSequence.cpp @@ -105,6 +105,7 @@ PyObject *py_ue_anim_extract_root_motion(ue_PyUObject * self, PyObject * args) #if WITH_EDITOR #if ENGINE_MINOR_VERSION > 13 +#if ENGINE_MINOR_VERSION < 23 PyObject *py_ue_anim_sequence_update_compressed_track_map_from_raw(ue_PyUObject * self, PyObject * args) { ue_py_check(self); @@ -117,6 +118,7 @@ PyObject *py_ue_anim_sequence_update_compressed_track_map_from_raw(ue_PyUObject Py_RETURN_NONE; } +#endif PyObject *py_ue_anim_sequence_get_raw_animation_data(ue_PyUObject * self, PyObject * args) diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyFoliage.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyFoliage.cpp index e474fda19..0a9498d2a 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyFoliage.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyFoliage.cpp @@ -37,8 +37,11 @@ PyObject *py_ue_get_foliage_types(ue_PyUObject *self, PyObject * args) PyObject *py_list = PyList_New(0); TArray FoliageTypes; - +#if ENGINE_MINOR_VERSION >=23 + foliage_actor->FoliageInfos.GetKeys(FoliageTypes); +#else foliage_actor->FoliageMeshes.GetKeys(FoliageTypes); +#endif for (UFoliageType *FoliageType : FoliageTypes) { @@ -68,12 +71,20 @@ PyObject *py_ue_get_foliage_instances(ue_PyUObject *self, PyObject * args) if (!foliage_type) return PyErr_Format(PyExc_Exception, "argument is not a UFoliageType"); +#if ENGINE_MINOR_VERSION >= 23 + if (!foliage_actor->FoliageInfos.Contains(foliage_type)) +#else if (!foliage_actor->FoliageMeshes.Contains(foliage_type)) +#endif { return PyErr_Format(PyExc_Exception, "specified UFoliageType not found in AInstancedFoliageActor"); } +#if ENGINE_MINOR_VERSION >= 23 + FFoliageInfo& info = foliage_actor->FoliageInfos[foliage_type].Get(); +#else FFoliageMeshInfo& info = foliage_actor->FoliageMeshes[foliage_type].Get(); +#endif PyObject *py_list = PyList_New(0); @@ -111,7 +122,11 @@ PyObject *py_ue_add_foliage_asset(ue_PyUObject *self, PyObject * args) AInstancedFoliageActor *ifa = AInstancedFoliageActor::GetInstancedFoliageActorForCurrentLevel(world, true); if (u_object->IsA()) { +#if ENGINE_MINOR_VERSION >= 23 + foliage_type = ifa->GetLocalFoliageTypeForSource(u_object); +#else foliage_type = ifa->GetLocalFoliageTypeForMesh((UStaticMesh *)u_object); +#endif if (!foliage_type) { ifa->AddMesh((UStaticMesh *)u_object, &foliage_type); diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp index fbd27d2df..adacab7ec 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyLandscape.cpp @@ -8,35 +8,35 @@ #include "Runtime/Landscape/Classes/LandscapeInfo.h" #include "GameFramework/GameModeBase.h" -PyObject *py_ue_create_landscape_info(ue_PyUObject *self, PyObject * args) +PyObject* py_ue_create_landscape_info(ue_PyUObject* self, PyObject* args) { ue_py_check(self); - ALandscapeProxy *landscape = ue_py_check_type(self); + ALandscapeProxy* landscape = ue_py_check_type(self); if (!landscape) return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy"); Py_RETURN_UOBJECT(landscape->CreateLandscapeInfo()); } -PyObject *py_ue_get_landscape_info(ue_PyUObject *self, PyObject * args) +PyObject* py_ue_get_landscape_info(ue_PyUObject* self, PyObject* args) { ue_py_check(self); - ALandscapeProxy *landscape = ue_py_check_type(self); + ALandscapeProxy* landscape = ue_py_check_type(self); if (!landscape) return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy"); - ULandscapeInfo *info = landscape->GetLandscapeInfo(); + ULandscapeInfo* info = landscape->GetLandscapeInfo(); if (!info) Py_RETURN_NONE; Py_RETURN_UOBJECT(info); } -PyObject *py_ue_landscape_import(ue_PyUObject *self, PyObject * args) +PyObject* py_ue_landscape_import(ue_PyUObject* self, PyObject* args) { ue_py_check(self); @@ -51,7 +51,7 @@ PyObject *py_ue_landscape_import(ue_PyUObject *self, PyObject * args) if (!PyArg_ParseTuple(args, "iiiiy*|i:landscape_import", §ion_size, §ions_per_component, &component_x, &component_y, &heightmap_buffer, &layer_type)) return nullptr; - ALandscapeProxy *landscape = ue_py_check_type(self); + ALandscapeProxy* landscape = ue_py_check_type(self); if (!landscape) return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy"); @@ -62,16 +62,29 @@ PyObject *py_ue_landscape_import(ue_PyUObject *self, PyObject * args) if (heightmap_buffer.len < (Py_ssize_t)(size_x * size_y * sizeof(uint16))) return PyErr_Format(PyExc_Exception, "not enough heightmap data, expecting %lu bytes", size_x * size_y * sizeof(uint16)); - uint16 *data = (uint16 *)heightmap_buffer.buf; + uint16* data = (uint16*)heightmap_buffer.buf; TArray infos; +#if ENGINE_MINOR_VERSION < 23 landscape->Import(FGuid::NewGuid(), 0, 0, size_x - 1, size_y - 1, sections_per_component, section_size, data, nullptr, infos, (ELandscapeImportAlphamapType)layer_type); +#else + TMap> HeightDataPerLayers; + TArray HeightData; + for (uint32 i = 0; i < (heightmap_buffer.len / sizeof(uint16)); i++) + { + HeightData.Add(data[i]); + } + HeightDataPerLayers.Add(FGuid(), HeightData); + TMap> MaterialLayersInfo; + MaterialLayersInfo.Add(FGuid(), infos); + landscape->Import(FGuid::NewGuid(), 0, 0, size_x - 1, size_y - 1, sections_per_component, section_size, HeightDataPerLayers, nullptr, MaterialLayersInfo, (ELandscapeImportAlphamapType)layer_type); +#endif Py_RETURN_NONE; } -PyObject *py_ue_landscape_export_to_raw_mesh(ue_PyUObject *self, PyObject * args) +PyObject* py_ue_landscape_export_to_raw_mesh(ue_PyUObject* self, PyObject* args) { ue_py_check(self); @@ -81,7 +94,7 @@ PyObject *py_ue_landscape_export_to_raw_mesh(ue_PyUObject *self, PyObject * args if (!PyArg_ParseTuple(args, "|i:landscape_import", &lod)) return nullptr; - ALandscapeProxy *landscape = ue_py_check_type(self); + ALandscapeProxy* landscape = ue_py_check_type(self); if (!landscape) return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy"); diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyMaterial.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyMaterial.cpp index 90b47da3a..c958094f6 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyMaterial.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyMaterial.cpp @@ -505,7 +505,11 @@ PyObject *py_ue_static_mesh_set_collision_for_lod(ue_PyUObject *self, PyObject * enabled = true; } +#if ENGINE_MINOR_VERSION >= 23 + FMeshSectionInfo info = mesh->GetSectionInfoMap().Get(lod_index, material_index); +#else FMeshSectionInfo info = mesh->SectionInfoMap.Get(lod_index, material_index); +#endif info.bEnableCollision = enabled; mesh->SectionInfoMap.Set(lod_index, material_index, info); diff --git a/Source/UnrealEnginePython/Private/Wrappers/UEPyESlateEnums.cpp b/Source/UnrealEnginePython/Private/Wrappers/UEPyESlateEnums.cpp index 4352312ba..7ffa2d05e 100644 --- a/Source/UnrealEnginePython/Private/Wrappers/UEPyESlateEnums.cpp +++ b/Source/UnrealEnginePython/Private/Wrappers/UEPyESlateEnums.cpp @@ -80,7 +80,11 @@ void ue_python_init_eslate_enums(PyObject *ue_module) }; #if ENGINE_MINOR_VERSION > 15 +#if ENGINE_MINOR_VERSION >= 23 +#define ADD_NATIVE_ENUM(EnumType, EnumVal) add_native_enum(#EnumType "." #EnumVal, (uint8)EnumType::EnumVal) +#else #define ADD_NATIVE_ENUM(EnumType, EnumVal) add_native_enum(#EnumType "." #EnumVal, (uint8)EnumType::Type::EnumVal) +#endif ADD_NATIVE_ENUM(EUserInterfaceActionType, None); ADD_NATIVE_ENUM(EUserInterfaceActionType, Button); ADD_NATIVE_ENUM(EUserInterfaceActionType, ToggleButton); diff --git a/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp b/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp index 1dbab35cd..eb48a0631 100644 --- a/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp +++ b/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp @@ -18,7 +18,7 @@ -static FFoliageInstance* get_foliage_instance(ue_PyFFoliageInstance *self) +static FFoliageInstance* get_foliage_instance(ue_PyFFoliageInstance* self) { if (!self->foliage_actor.IsValid()) { @@ -32,7 +32,13 @@ static FFoliageInstance* get_foliage_instance(ue_PyFFoliageInstance *self) return nullptr; } +#if ENGINE_MINOR_VERSION >= 23 + auto FoliageInfo = self->foliage_actor->FoliageInfos[self->foliage_type.Get()]; + FFoliageInfo& info = info; +#else + FFoliageMeshInfo& info = self->foliage_actor->FoliageMeshes[self->foliage_type.Get()].Get(); +#endif if (self->instance_id >= 0 && self->instance_id < info.Instances.Num()) { @@ -43,25 +49,25 @@ static FFoliageInstance* get_foliage_instance(ue_PyFFoliageInstance *self) return nullptr; } -static PyObject *ue_PyFFoliageInstance_str(ue_PyFFoliageInstance *self) +static PyObject* ue_PyFFoliageInstance_str(ue_PyFFoliageInstance* self) { return PyUnicode_FromFormat("", self->instance_id); } -static PyObject *py_ue_ffoliage_instance_get_location(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_location(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return py_ue_new_fvector(instance->Location); } -static int py_ue_ffoliage_instance_set_location(ue_PyFFoliageInstance *self, PyObject *value, void *closure) +static int py_ue_ffoliage_instance_set_location(ue_PyFFoliageInstance* self, PyObject* value, void* closure) { set_instance(self); if (value) { - ue_PyFVector *vec = py_ue_is_fvector(value); + ue_PyFVector* vec = py_ue_is_fvector(value); if (vec) { TArray instances; @@ -77,12 +83,12 @@ static int py_ue_ffoliage_instance_set_location(ue_PyFFoliageInstance *self, PyO return -1; } -static int py_ue_ffoliage_instance_set_rotation(ue_PyFFoliageInstance *self, PyObject *value, void *closure) +static int py_ue_ffoliage_instance_set_rotation(ue_PyFFoliageInstance* self, PyObject* value, void* closure) { set_instance(self); if (value) { - ue_PyFRotator *rot = py_ue_is_frotator(value); + ue_PyFRotator* rot = py_ue_is_frotator(value); if (rot) { TArray instances; @@ -98,56 +104,56 @@ static int py_ue_ffoliage_instance_set_rotation(ue_PyFFoliageInstance *self, PyO return -1; } -static PyObject *py_ue_ffoliage_instance_get_draw_scale3d(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_draw_scale3d(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return py_ue_new_fvector(instance->DrawScale3D); } -static PyObject *py_ue_ffoliage_instance_get_flags(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_flags(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return PyLong_FromUnsignedLong(instance->Flags); } -static PyObject *py_ue_ffoliage_instance_get_pre_align_rotation(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_pre_align_rotation(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return py_ue_new_frotator(instance->PreAlignRotation); } -static PyObject *py_ue_ffoliage_instance_get_rotation(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_rotation(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return py_ue_new_frotator(instance->Rotation); } -static PyObject *py_ue_ffoliage_instance_get_zoffset(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_zoffset(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return PyFloat_FromDouble(instance->ZOffset); } -static PyObject *py_ue_ffoliage_instance_get_procedural_guid(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_procedural_guid(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); FGuid guid = instance->ProceduralGuid; - return py_ue_new_owned_uscriptstruct(FindObject(ANY_PACKAGE, UTF8_TO_TCHAR((char *)"Guid")), (uint8 *)&guid); + return py_ue_new_owned_uscriptstruct(FindObject(ANY_PACKAGE, UTF8_TO_TCHAR((char*)"Guid")), (uint8*)& guid); } -static PyObject *py_ue_ffoliage_instance_get_base_id(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_base_id(ue_PyFFoliageInstance* self, void* closure) { get_instance(self); return PyLong_FromLong(instance->BaseId); } -static PyObject *py_ue_ffoliage_instance_get_instance_id(ue_PyFFoliageInstance *self, void *closure) +static PyObject* py_ue_ffoliage_instance_get_instance_id(ue_PyFFoliageInstance* self, void* closure) { return PyLong_FromLong(self->instance_id); } #if ENGINE_MINOR_VERSION > 19 -static PyObject *py_ue_ffoliage_instance_get_base_component(ue_PyFFoliageInstance *self, void *closure) +static PyObject * py_ue_ffoliage_instance_get_base_component(ue_PyFFoliageInstance * self, void* closure) { get_instance(self); Py_RETURN_UOBJECT(instance->BaseComponent); @@ -157,39 +163,39 @@ static PyObject *py_ue_ffoliage_instance_get_base_component(ue_PyFFoliageInstanc static PyGetSetDef ue_PyFFoliageInstance_getseters[] = { - { (char *)"location", (getter)py_ue_ffoliage_instance_get_location, (setter)py_ue_ffoliage_instance_set_location, (char *)"", NULL }, - { (char *)"draw_scale3d", (getter)py_ue_ffoliage_instance_get_draw_scale3d, nullptr, (char *)"", NULL }, - { (char *)"flags", (getter)py_ue_ffoliage_instance_get_flags, nullptr, (char *)"", NULL }, - { (char *)"pre_align_rotation", (getter)py_ue_ffoliage_instance_get_pre_align_rotation, nullptr, (char *)"", NULL }, - { (char *)"rotation", (getter)py_ue_ffoliage_instance_get_rotation, (setter)py_ue_ffoliage_instance_set_rotation, (char *)"", NULL }, - { (char *)"zoffset", (getter)py_ue_ffoliage_instance_get_zoffset, nullptr, (char *)"", NULL }, - { (char *)"procedural_guid", (getter)py_ue_ffoliage_instance_get_procedural_guid, nullptr, (char *)"", NULL }, - { (char *)"guid", (getter)py_ue_ffoliage_instance_get_procedural_guid, nullptr, (char *)"", NULL }, - { (char *)"base_id", (getter)py_ue_ffoliage_instance_get_base_id, nullptr, (char *)"", NULL }, - { (char *)"instance_id", (getter)py_ue_ffoliage_instance_get_instance_id, nullptr, (char *)"", NULL }, + { (char*)"location", (getter)py_ue_ffoliage_instance_get_location, (setter)py_ue_ffoliage_instance_set_location, (char*)"", NULL }, + { (char*)"draw_scale3d", (getter)py_ue_ffoliage_instance_get_draw_scale3d, nullptr, (char*)"", NULL }, + { (char*)"flags", (getter)py_ue_ffoliage_instance_get_flags, nullptr, (char*)"", NULL }, + { (char*)"pre_align_rotation", (getter)py_ue_ffoliage_instance_get_pre_align_rotation, nullptr, (char*)"", NULL }, + { (char*)"rotation", (getter)py_ue_ffoliage_instance_get_rotation, (setter)py_ue_ffoliage_instance_set_rotation, (char*)"", NULL }, + { (char*)"zoffset", (getter)py_ue_ffoliage_instance_get_zoffset, nullptr, (char*)"", NULL }, + { (char*)"procedural_guid", (getter)py_ue_ffoliage_instance_get_procedural_guid, nullptr, (char*)"", NULL }, + { (char*)"guid", (getter)py_ue_ffoliage_instance_get_procedural_guid, nullptr, (char*)"", NULL }, + { (char*)"base_id", (getter)py_ue_ffoliage_instance_get_base_id, nullptr, (char*)"", NULL }, + { (char*)"instance_id", (getter)py_ue_ffoliage_instance_get_instance_id, nullptr, (char*)"", NULL }, #if ENGINE_MINOR_VERSION > 19 - { (char *)"base_component", (getter)py_ue_ffoliage_instance_get_base_component, nullptr, (char *)"", NULL }, + { (char*)"base_component", (getter)py_ue_ffoliage_instance_get_base_component, nullptr, (char*)"", NULL }, #endif { NULL } /* Sentinel */ }; -static PyObject *py_ue_ffoliage_instance_get_instance_world_transform(ue_PyFFoliageInstance *self, PyObject * args) +static PyObject* py_ue_ffoliage_instance_get_instance_world_transform(ue_PyFFoliageInstance* self, PyObject* args) { get_instance(self); return py_ue_new_ftransform(instance->GetInstanceWorldTransform()); } -static PyObject *py_ue_ffoliage_instance_align_to_normal(ue_PyFFoliageInstance *self, PyObject * args) +static PyObject* py_ue_ffoliage_instance_align_to_normal(ue_PyFFoliageInstance* self, PyObject* args) { get_instance(self); - PyObject *py_vec; + PyObject* py_vec; float align_max_angle = 0; if (!PyArg_ParseTuple(args, "O|f:align_to_normal", &py_vec, &align_max_angle)) return nullptr; - ue_PyFVector *vec = py_ue_is_fvector(py_vec); + ue_PyFVector* vec = py_ue_is_fvector(py_vec); if (!vec) { return PyErr_Format(PyExc_Exception, "argument is not an FVector"); @@ -244,7 +250,7 @@ static PyTypeObject ue_PyFFoliageInstanceType = { ue_PyFFoliageInstance_getseters, }; -void ue_python_init_ffoliage_instance(PyObject *ue_module) +void ue_python_init_ffoliage_instance(PyObject* ue_module) { ue_PyFFoliageInstanceType.tp_new = PyType_GenericNew; @@ -252,16 +258,16 @@ void ue_python_init_ffoliage_instance(PyObject *ue_module) return; Py_INCREF(&ue_PyFFoliageInstanceType); - PyModule_AddObject(ue_module, "FoliageInstance", (PyObject *)&ue_PyFFoliageInstanceType); + PyModule_AddObject(ue_module, "FoliageInstance", (PyObject*)& ue_PyFFoliageInstanceType); } -PyObject *py_ue_new_ffoliage_instance(AInstancedFoliageActor *foliage_actor, UFoliageType *foliage_type, int32 instance_id) +PyObject* py_ue_new_ffoliage_instance(AInstancedFoliageActor* foliage_actor, UFoliageType* foliage_type, int32 instance_id) { - ue_PyFFoliageInstance *ret = (ue_PyFFoliageInstance *)PyObject_New(ue_PyFFoliageInstance, &ue_PyFFoliageInstanceType); + ue_PyFFoliageInstance* ret = (ue_PyFFoliageInstance*)PyObject_New(ue_PyFFoliageInstance, &ue_PyFFoliageInstanceType); ret->foliage_actor = TWeakObjectPtr(foliage_actor); ret->foliage_type = TWeakObjectPtr(foliage_type); ret->instance_id = instance_id; - return (PyObject *)ret; + return (PyObject*)ret; } #endif \ No newline at end of file diff --git a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs index 51394b033..92376225e 100644 --- a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs +++ b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs @@ -18,7 +18,7 @@ public class UnrealEnginePython : ModuleRules private string[] windowsKnownPaths = { - "C:/Program Files/Python37", + // "C:/Program Files/Python37", "C:/Program Files/Python36", "C:/Program Files/Python35", "C:/Python27", From 038192d7814d1aee182766028640d238204fefa4 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Wed, 11 Sep 2019 05:27:13 +0200 Subject: [PATCH 20/23] completed porting to 4.23. fixes #777 --- .../Private/Slate/UEPySTextBlock.cpp | 4 ++++ Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp | 5 ++++- Source/UnrealEnginePython/Private/UEPyModule.cpp | 2 ++ .../UnrealEnginePython/Private/UObject/UEPyObject.cpp | 4 ++++ .../Private/Wrappers/UEPyFFoliageInstance.cpp | 11 +++++++++-- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp b/Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp index a994186a5..92df02d50 100644 --- a/Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp +++ b/Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp @@ -70,7 +70,11 @@ static int ue_py_stext_block_init(ue_PySTextBlock *self, PyObject *args, PyObjec ue_py_slate_farguments_float("line_height_percentage", LineHeightPercentage); ue_py_slate_farguments_struct("margin", Margin, FMargin); ue_py_slate_farguments_float("min_desired_width", MinDesiredWidth); +#if ENGINE_MINOR_VERSION >= 23 + ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FPointerEventHandler, OnMouseEvent); +#else ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FOnClicked, OnClicked); +#endif ue_py_slate_farguments_flinear_color("shadow_color_and_opacity", ShadowColorAndOpacity); ue_py_slate_farguments_fvector2d("shadow_offset", ShadowOffset); ue_py_slate_farguments_text("text", Text); diff --git a/Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp b/Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp index 0cc988240..2e705a303 100644 --- a/Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp +++ b/Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp @@ -1020,8 +1020,11 @@ class FPythonSlateCommands : public TCommands virtual void RegisterCommands() override { commands = MakeShareable(new FUICommandList); - +#if ENGINE_MINOR_VERSION >= 23 + MakeUICommand_InternalUseOnly(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture()); +#else UI_COMMAND_Function(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture()); +#endif commands->MapAction(command, FExecuteAction::CreateRaw(this, &FPythonSlateCommands::Callback), FCanExecuteAction()); } diff --git a/Source/UnrealEnginePython/Private/UEPyModule.cpp b/Source/UnrealEnginePython/Private/UEPyModule.cpp index b725ae7f0..56954d32e 100644 --- a/Source/UnrealEnginePython/Private/UEPyModule.cpp +++ b/Source/UnrealEnginePython/Private/UEPyModule.cpp @@ -744,7 +744,9 @@ static PyMethodDef ue_PyUObject_methods[] = { { "get_raw_animation_data", (PyCFunction)py_ue_anim_sequence_get_raw_animation_data, METH_VARARGS, "" }, { "get_raw_animation_track", (PyCFunction)py_ue_anim_sequence_get_raw_animation_track, METH_VARARGS, "" }, { "add_new_raw_track", (PyCFunction)py_ue_anim_sequence_add_new_raw_track, METH_VARARGS, "" }, +#if ENGINE_MINOR_VERSION <23 { "update_compressed_track_map_from_raw", (PyCFunction)py_ue_anim_sequence_update_compressed_track_map_from_raw, METH_VARARGS, "" }, +#endif { "update_raw_track", (PyCFunction)py_ue_anim_sequence_update_raw_track, METH_VARARGS, "" }, { "apply_raw_anim_changes", (PyCFunction)py_ue_anim_sequence_apply_raw_anim_changes, METH_VARARGS, "" }, { "add_key_to_sequence", (PyCFunction)py_ue_anim_add_key_to_sequence, METH_VARARGS, "" }, diff --git a/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp b/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp index d11031775..3b2983b99 100644 --- a/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp +++ b/Source/UnrealEnginePython/Private/UObject/UEPyObject.cpp @@ -1084,7 +1084,11 @@ PyObject *py_ue_broadcast(ue_PyUObject *self, PyObject *args) if (auto casted_prop = Cast(u_property)) { +#if ENGINE_MINOR_VERSION >= 23 + FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(self->ue_object); +#else FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(self->ue_object); +#endif uint8 *parms = (uint8 *)FMemory_Alloca(casted_prop->SignatureFunction->PropertiesSize); FMemory::Memzero(parms, casted_prop->SignatureFunction->PropertiesSize); diff --git a/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp b/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp index eb48a0631..2ed7ffa2d 100644 --- a/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp +++ b/Source/UnrealEnginePython/Private/Wrappers/UEPyFFoliageInstance.cpp @@ -33,8 +33,7 @@ static FFoliageInstance* get_foliage_instance(ue_PyFFoliageInstance* self) } #if ENGINE_MINOR_VERSION >= 23 - auto FoliageInfo = self->foliage_actor->FoliageInfos[self->foliage_type.Get()]; - FFoliageInfo& info = info; + FFoliageInfo& info = self->foliage_actor->FoliageInfos[self->foliage_type.Get()].Get(); #else FFoliageMeshInfo& info = self->foliage_actor->FoliageMeshes[self->foliage_type.Get()].Get(); @@ -72,7 +71,11 @@ static int py_ue_ffoliage_instance_set_location(ue_PyFFoliageInstance* self, PyO { TArray instances; instances.Add(self->instance_id); +#if ENGINE_MINOR_VERSION >= 23 + FFoliageInfo& info = self->foliage_actor->FoliageInfos[self->foliage_type.Get()].Get(); +#else FFoliageMeshInfo& info = self->foliage_actor->FoliageMeshes[self->foliage_type.Get()].Get(); +#endif info.PreMoveInstances(self->foliage_actor.Get(), instances); instance->Location = vec->vec; info.PostMoveInstances(self->foliage_actor.Get(), instances); @@ -93,7 +96,11 @@ static int py_ue_ffoliage_instance_set_rotation(ue_PyFFoliageInstance* self, PyO { TArray instances; instances.Add(self->instance_id); +#if ENGINE_MINOR_VERSION >= 23 + FFoliageInfo& info = self->foliage_actor->FoliageInfos[self->foliage_type.Get()].Get(); +#else FFoliageMeshInfo& info = self->foliage_actor->FoliageMeshes[self->foliage_type.Get()].Get(); +#endif info.PreMoveInstances(self->foliage_actor.Get(), instances); instance->Rotation = rot->rot; info.PostMoveInstances(self->foliage_actor.Get(), instances); From b0366cbada1e6b7c951258f35ad3868e45f19ca4 Mon Sep 17 00:00:00 2001 From: Hamilton Greene Date: Tue, 26 Nov 2019 23:21:34 -0500 Subject: [PATCH 21/23] Add ; to the end of the Linux UnrealEnginePython.Build.cs pythonHome example Adding for consistency with the other examples. --- Source/UnrealEnginePython/UnrealEnginePython.Build.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs index 92376225e..a6fe71946 100644 --- a/Source/UnrealEnginePython/UnrealEnginePython.Build.cs +++ b/Source/UnrealEnginePython/UnrealEnginePython.Build.cs @@ -14,7 +14,7 @@ public class UnrealEnginePython : ModuleRules // this is an example for Homebrew on Mac //private string pythonHome = "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/"; // on Linux an include;libs syntax is expected: - //private string pythonHome = "/usr/local/include/python3.6;/usr/local/lib/libpython3.6.so" + //private string pythonHome = "/usr/local/include/python3.6;/usr/local/lib/libpython3.6.so"; private string[] windowsKnownPaths = { From bb2f38df55f0f860b161c5bf54554f36eebb5f38 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Wed, 4 Mar 2020 11:31:52 +0100 Subject: [PATCH 22/23] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index ee231ff61..a7fa3522a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,16 @@ Funny snippets for working with StaticMesh and SkeletalMesh assets: https://gith More tutorials: https://github.com/20tab/UnrealEnginePython/tree/master/tutorials +# Project Status (IMPORTANT) + +Currently (as march 2020) the project is basically dead: between 2016 and 2018 20tab invested lot of resources in it but unfortunately epic (during 2018) decided to suddenly release its own implementation and the request made for a megagrant in 2019 by the original plugin author was rejected too. + +Albeit this plugin (still) has way more features than the Epic one, this is not enough to allow 20tab to continue investing in it. + +If you are interested in game logic scripting/modding in Unreal Engine 4 consider giving a look at the LuaMachine project (https://github.com/rdeioris/LuaMachine/). + +The plugin should work up to unreal engine version 4.23 and there are forks/pull requests for 4.24. Since 4.25 Epic refactored the UProperty subsystem, so if you want to port the plugin to a version >= 4.25 you should make a lot of search & replace (basically renaming UProperty to FProperty and Cast to CastField should be enough) + # How and Why ? This is a plugin embedding a whole Python VM (versions 3.x [the default and suggested one] and 2.7) In Unreal Engine 4 (both the editor and runtime). From 4b5da5bf4ca598e8d0f67eb938749bc381a67d6c Mon Sep 17 00:00:00 2001 From: Gabriele Giaccari Date: Fri, 17 Apr 2020 09:38:21 +0200 Subject: [PATCH 23/23] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a7fa3522a..68ed706f1 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ More tutorials: https://github.com/20tab/UnrealEnginePython/tree/master/tutorial # Project Status (IMPORTANT) -Currently (as march 2020) the project is basically dead: between 2016 and 2018 20tab invested lot of resources in it but unfortunately epic (during 2018) decided to suddenly release its own implementation and the request made for a megagrant in 2019 by the original plugin author was rejected too. +Currently (as april 2020) the project is on hold: between 2016 and 2018 20tab invested lot of resources in it but unfortunately epic (during 2018) decided to suddenly release its own implementation and the request made for a megagrant in 2019 by the original plugin author was rejected too. -Albeit this plugin (still) has way more features than the Epic one, this is not enough to allow 20tab to continue investing in it. +As this plugin (still) has way more features than the Epic one and many contributors, **we are currently looking for new maintainers** helping us to keep it alive, checking PR and issues. If you are interested in working on it a few hours a week, drop us a line at info@20tab.com to discuss about it. If you are interested in game logic scripting/modding in Unreal Engine 4 consider giving a look at the LuaMachine project (https://github.com/rdeioris/LuaMachine/).