diff --git a/Source/Editor/SceneGraph/ActorNode.cs b/Source/Editor/SceneGraph/ActorNode.cs index 3542feb03..6703c30a0 100644 --- a/Source/Editor/SceneGraph/ActorNode.cs +++ b/Source/Editor/SceneGraph/ActorNode.cs @@ -288,6 +288,13 @@ namespace FlaxEditor.SceneGraph { } + /// + /// Action called after pasting actor in editor. + /// + public virtual void PostPaste() + { + } + /// protected override void OnParentChanged() { diff --git a/Source/Editor/SceneGraph/Actors/UIControlNode.cs b/Source/Editor/SceneGraph/Actors/UIControlNode.cs index b3f8f5d09..c4f7d1c17 100644 --- a/Source/Editor/SceneGraph/Actors/UIControlNode.cs +++ b/Source/Editor/SceneGraph/Actors/UIControlNode.cs @@ -25,5 +25,20 @@ namespace FlaxEditor.SceneGraph.Actors if (Actor is UIControl uiControl) DebugDraw.DrawWireBox(uiControl.Bounds, Color.BlueViolet); } + + /// + public override void PostPaste() + { + base.PostPaste(); + + var control = ((UIControl)Actor).Control; + if (control != null) + { + if (control.Parent != null) + control.Parent.PerformLayout(); + else + control.PerformLayout(); + } + } } } diff --git a/Source/Editor/Undo/Actions/PasteActorsAction.cs b/Source/Editor/Undo/Actions/PasteActorsAction.cs index c65aa6bf0..c77feb71d 100644 --- a/Source/Editor/Undo/Actions/PasteActorsAction.cs +++ b/Source/Editor/Undo/Actions/PasteActorsAction.cs @@ -140,22 +140,27 @@ namespace FlaxEditor.Actions for (int i = 0; i < nodeParents.Count; i++) { - // Fix name collisions (only for parents) var node = nodeParents[i]; var parent = node.Actor?.Parent; if (parent != null) { + // Fix name collisions string name = node.Name; Actor[] children = parent.Children; if (children.Any(x => x.Name == name)) { - // Generate new name node.Actor.Name = StringUtils.IncrementNameNumber(name, x => children.All(y => y.Name != x)); } } Editor.Instance.Scene.MarkSceneEdited(node.ParentScene); } + + for (int i = 0; i < nodeParents.Count; i++) + { + var node = nodeParents[i]; + node.PostPaste(); + } } /// diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 21e2ae050..93f5c05c6 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -16,6 +16,7 @@ #include "Engine/Core/Collections/CollectionPoolCache.h" #include "Engine/Debug/Exceptions/JsonParseException.h" #include "Engine/Graphics/RenderView.h" +#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Serialization/ISerializeModifier.h" #include "Engine/Serialization/Serialization.h" @@ -1494,6 +1495,7 @@ void WriteObjectToBytes(SceneObject* obj, rapidjson_flax::StringBuffer& buffer, bool Actor::ToBytes(const Array& actors, MemoryWriteStream& output) { + PROFILE_CPU(); if (actors.IsEmpty()) { // Cannot serialize empty list @@ -1553,6 +1555,7 @@ Array Actor::ToBytes(const Array& actors) bool Actor::FromBytes(const Span& data, Array& output, ISerializeModifier* modifier) { + PROFILE_CPU(); output.Clear(); ASSERT(modifier); @@ -1654,17 +1657,19 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM Scripting::ObjectsLookupIdMapping.Set(nullptr); // Link objects - for (int32 i = 0; i < objectsCount; i++) + //for (int32 i = 0; i < objectsCount; i++) { - SceneObject* obj = sceneObjects->At(i); - obj->PostLoad(); + //SceneObject* obj = sceneObjects->At(i); + // TODO: post load or post spawn? + //obj->PostLoad(); } // Update objects order - for (int32 i = 0; i < objectsCount; i++) + //for (int32 i = 0; i < objectsCount; i++) { - SceneObject* obj = sceneObjects->At(i); - obj->SetOrderInParent(order[i]); + //SceneObject* obj = sceneObjects->At(i); + // TODO: remove order from saved data? + //obj->SetOrderInParent(order[i]); } // Call events (only for parents because they will propagate events down the tree) @@ -1681,6 +1686,10 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM } } for (int32 i = 0; i < parents->Count(); i++) + { + parents->At(i)->PostSpawn(); + } + for (int32 i = 0; i < parents->Count(); i++) { Actor* actor = parents->At(i); actor->OnTransformChanged(); @@ -1722,6 +1731,7 @@ Array Actor::FromBytes(const Span& data, const Dictionary Actor::TryGetSerializedObjectsIds(const Span& data) { + PROFILE_CPU(); Array result; if (data.Length() > 0) { @@ -1742,6 +1752,7 @@ Array Actor::TryGetSerializedObjectsIds(const Span& data) String Actor::ToJson() { + PROFILE_CPU(); rapidjson_flax::StringBuffer buffer; CompactJsonWriter writer(buffer); writer.SceneObject(this); @@ -1753,6 +1764,8 @@ String Actor::ToJson() void Actor::FromJson(const StringAnsiView& json) { + PROFILE_CPU(); + // Load JSON rapidjson_flax::Document document; document.Parse(json.Get(), json.Length()); diff --git a/Source/Engine/UI/UIControl.cs b/Source/Engine/UI/UIControl.cs index b8f8b00dd..d981c1b6c 100644 --- a/Source/Engine/UI/UIControl.cs +++ b/Source/Engine/UI/UIControl.cs @@ -52,7 +52,6 @@ namespace FlaxEngine _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; _control.Location = new Vector2(LocalPosition); - // TODO: sync control order in parent with actor order in parent (think about special cases like Panel with scroll bars used as internal controls) _control.LocationChanged += OnControlLocationChanged; // Link children UI controls @@ -353,6 +352,7 @@ namespace FlaxEngine if (_control != null) { _control.Parent = GetParent(); + _control.IndexInParent = OrderInParent; } }