Quellcode durchsuchen

More work on multiediting

Josh Engebretson vor 10 Jahren
Ursprung
Commit
9da8b2fbd2

+ 3 - 3
Script/AtomicEditor/ui/frames/inspector/ComponentInspector.ts

@@ -97,7 +97,7 @@ class ComponentInspector extends Atomic.UISection {
         this.text = component.typeName;
 
         component.scene.sendEvent("SceneEditSerializable", { serializable: component, operation: 0});
-        this.subscribeToEvent(component, "SceneEditSerializableUndoRedo", (data) => this.handleSceneEditSerializableUndoRedoEvent(data));
+        this.subscribeToEvent(component, "SceneEditStateChange", (data) => this.handleSceneEditStateChangeEvent(data));
 
         // For JSComponents append the filename
         if (component.typeName == "JSComponent") {
@@ -214,7 +214,7 @@ class ComponentInspector extends Atomic.UISection {
 
             // refresh entire inspector, fix this...
             this.sendEvent("EditorActiveNodeChange", { node: node });
-            
+
             return true;
 
         }
@@ -296,7 +296,7 @@ class ComponentInspector extends Atomic.UISection {
 
     }
 
-    handleSceneEditSerializableUndoRedoEvent(ev) {
+    handleSceneEditStateChangeEvent(ev) {
 
       for (var i in this.bindings) {
           this.bindings[i].objectLocked = true;

+ 3 - 3
Script/AtomicEditor/ui/frames/inspector/DataBinding.ts

@@ -464,7 +464,7 @@ class DataBinding {
       if (!scene)
           return;
 
-      scene.sendEvent("SceneEditSerializable", { serializable: this.object, operation: 1 });
+      scene.sendEvent("SceneEditEnd");
 
     }
 
@@ -483,7 +483,7 @@ class DataBinding {
                 this.setWidgetValueFromObject();
                 // TODO: once new base class stuff is in, should be able to check for type
                 if (this.object["scene"])
-                    this.object["scene"].sendEvent("SceneEditSerializable", { serializable: this.object, operation: 1 });
+                    this.object["scene"].sendEvent("SceneEditEnd");
 
 
             }
@@ -515,7 +515,7 @@ class DataBinding {
 
                     // TODO: once new base class stuff is in, should be able to check for type
                     if (this.object["scene"])
-                        this.object["scene"].sendEvent("SceneEditSerializable", { serializable: this.object, operation: 1 });
+                        this.object["scene"].sendEvent("SceneEditEnd");
                 }
 
                 return true;

+ 2 - 2
Script/AtomicEditor/ui/frames/inspector/NodeInspector.ts

@@ -135,7 +135,7 @@ class NodeInspector extends ScriptWidget {
         this.node = node;
 
         node.scene.sendEvent("SceneEditSerializable", { serializable: node, operation: 0 });
-        this.subscribeToEvent(node, "SceneEditSerializableUndoRedo", (data) => this.handleSceneEditSerializableUndoRedoEvent(data));
+        this.subscribeToEvent(node, "SceneEditStateChange", (data) => this.handleSceneEditStateChangeEvent(data));
 
         this.isPrefab = this.detectPrefab(node);
 
@@ -335,7 +335,7 @@ class NodeInspector extends ScriptWidget {
 
     }
 
-    handleSceneEditSerializableUndoRedoEvent(ev) {
+    handleSceneEditStateChangeEvent(ev) {
 
         for (var i in this.bindings) {
             this.bindings[i].objectLocked = true;

+ 62 - 8
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditHistory.cpp

@@ -1,4 +1,7 @@
 
+#include <Atomic/IO/Log.h>
+#include <Atomic/Scene/SceneEvents.h>
+
 #include "SceneEditor3D.h"
 
 #include "SceneEditor3DEvents.h"
@@ -11,13 +14,19 @@ namespace AtomicEditor
 
 SceneEditHistory::SceneEditHistory(Context* context, SceneEditor3D* sceneEditor) : Object(context),
     sceneEditor_(sceneEditor),
-    curSelEditOp_(0)
+    curSelEditOp_(0),
+    addingRemovingNodes_(false)
 {
     SubscribeToEvent(sceneEditor_->GetScene(), E_SCENENODESELECTED, HANDLER(SceneEditHistory, HandleSceneNodeSelected));
 
     SubscribeToEvent(sceneEditor_->GetScene(), E_SCENEEDITBEGIN, HANDLER(SceneEditHistory, HandleSceneEditBegin));
     SubscribeToEvent(sceneEditor_->GetScene(), E_SCENEEDITEND, HANDLER(SceneEditHistory, HandleSceneEditEnd));
 
+    SubscribeToEvent(sceneEditor_->GetScene(), E_SCENEEDITADDREMOVENODES, HANDLER(SceneEditHistory, HandleSceneEditAddRemoveNodes));
+
+    SubscribeToEvent(sceneEditor_->GetScene(), E_NODEADDED, HANDLER(SceneEditHistory, HandleNodeAdded));
+    SubscribeToEvent(sceneEditor_->GetScene(), E_NODEREMOVED, HANDLER(SceneEditHistory, HandleNodeRemoved));
+
 }
 
 SceneEditHistory::~SceneEditHistory()
@@ -36,15 +45,47 @@ void SceneEditHistory::HandleSceneEditEnd(StringHash eventType, VariantMap& even
     EndSelectionEdit();
 }
 
-void SceneEditHistory::BeginSelectionEdit()
+void SceneEditHistory::HandleSceneEditAddRemoveNodes(StringHash eventType, VariantMap& eventData)
 {
-    assert(!curSelEditOp_);
 
-    Vector<SharedPtr<Node>>& nodes = sceneEditor_->GetSelection()->GetNodes();
-    if (!nodes.Size())
+    bool end = eventData[SceneEditAddRemoveNodes::P_END].GetBool();
+
+    if (end)
+    {
+        addingRemovingNodes_ = false;
+
+        EndSelectionEdit(true);
+    }
+    else
+    {
+        addingRemovingNodes_ = true;
+        EndSelectionEdit(false);
+
+        curSelEditOp_ = new SelectionEditOp();
+
+    }
+}
+
+void SceneEditHistory::HandleNodeAdded(StringHash eventType, VariantMap& eventData)
+{
+    if (!addingRemovingNodes_)
         return;
 
-    curSelEditOp_ = new SelectionEditOp(nodes);
+    Node* node = static_cast<Node*>(eventData[NodeAdded::P_NODE].GetPtr());
+    Node* parent = static_cast<Node*>(eventData[NodeAdded::P_PARENT].GetPtr());
+
+    curSelEditOp_->NodeAdded(node, parent);
+}
+
+void SceneEditHistory::HandleNodeRemoved(StringHash eventType, VariantMap& eventData)
+{
+    if (!addingRemovingNodes_)
+        return;
+
+    Node* node = static_cast<Node*>(eventData[NodeAdded::P_NODE].GetPtr());
+    Node* parent = static_cast<Node*>(eventData[NodeAdded::P_PARENT].GetPtr());
+
+    curSelEditOp_->NodeRemoved(node, parent);
 }
 
 void SceneEditHistory::AddUndoOp(SelectionEditOp* op)
@@ -61,7 +102,19 @@ void SceneEditHistory::AddUndoOp(SelectionEditOp* op)
     redoHistory_.Clear();
 }
 
-void SceneEditHistory::EndSelectionEdit()
+void SceneEditHistory::BeginSelectionEdit()
+{
+    assert(!curSelEditOp_);
+
+    Vector<SharedPtr<Node>>& nodes = sceneEditor_->GetSelection()->GetNodes();
+    if (!nodes.Size())
+        return;
+
+    curSelEditOp_ = new SelectionEditOp();
+    curSelEditOp_->SetNodes(nodes);
+}
+
+void SceneEditHistory::EndSelectionEdit(bool begin)
 {
     if (!curSelEditOp_)
         return;
@@ -79,7 +132,8 @@ void SceneEditHistory::EndSelectionEdit()
 
     curSelEditOp_ = 0;
 
-    BeginSelectionEdit();
+    if (begin)
+        BeginSelectionEdit();
 
 }
 

+ 11 - 1
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditHistory.h

@@ -11,6 +11,11 @@
 
 using namespace Atomic;
 
+namespace Atomic
+{
+class Node;
+}
+
 namespace AtomicEditor
 {
 
@@ -27,7 +32,7 @@ public:
     virtual ~SceneEditHistory();
 
     void BeginSelectionEdit();
-    void EndSelectionEdit();
+    void EndSelectionEdit(bool begin = true);
 
     void Undo();
     void Redo();
@@ -37,6 +42,9 @@ private:
     void HandleSceneNodeSelected(StringHash eventType, VariantMap& eventData);
     void HandleSceneEditBegin(StringHash eventType, VariantMap& eventData);
     void HandleSceneEditEnd(StringHash eventType, VariantMap& eventData);
+    void HandleSceneEditAddRemoveNodes(StringHash eventType, VariantMap& eventData);
+    void HandleNodeAdded(StringHash eventType, VariantMap& eventData);
+    void HandleNodeRemoved(StringHash eventType, VariantMap& eventData);
 
     void AddUndoOp(SelectionEditOp* op);
 
@@ -47,6 +55,8 @@ private:
     PODVector<SelectionEditOp*> undoHistory_;
     PODVector<SelectionEditOp*> redoHistory_;
 
+    bool addingRemovingNodes_;
+
 };
 
 }

+ 112 - 44
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditOp.cpp

@@ -2,64 +2,105 @@
 #include <Atomic/IO/Log.h>
 #include <Atomic/Scene/Node.h>
 #include <Atomic/Scene/Component.h>
+#include <Atomic/Scene/Scene.h>
 
 #include "SceneEditOp.h"
+#include "SceneEditor3DEvents.h"
 
 namespace AtomicEditor
 {
 
-SelectionEditOp::SelectionEditOp(Vector<SharedPtr<Node>>& nodes) : SceneEditOp(SCENEEDIT_SELECTION)
+SelectionEditOp::SelectionEditOp() : SceneEditOp(SCENEEDIT_SELECTION)
 {
-    // Generate initial snapshot
-    for (unsigned i = 0; i < nodes.Size(); i++)
+}
+
+SelectionEditOp::~SelectionEditOp()
+{
+
+    for (unsigned i = 0; i < editNodes_.Size(); i++)
     {
-        Node* node = nodes[i];
+        EditNode* enode = editNodes_[i];
+        for (unsigned j = 0; j < enode->components_.Size(); j++)
+            delete enode->components_[j];
+        delete enode;
+    }
 
-        if (node->IsTemporary())
-            continue;
+}
 
-        EditNode* enode = new EditNode();
-        enode->node_ = node;
-        enode->parentBegin_ = enode->parentEnd_ = node->GetParent();
-        node->Serializable::Save(enode->stateBegin_);
-        enode->stateBegin_.Seek(0);
-        enode->stateEnd_ = enode->stateBegin_;
+void SelectionEditOp::AddNode(Node* node)
+{
 
-        const Vector<SharedPtr<Component>>& components = node->GetComponents();
+    for (unsigned i = 0; i < editNodes_.Size(); i++)
+    {
+        if (editNodes_[i]->node_ == node)
+            return;
+    }
 
-        for (unsigned j = 0; j < components.Size(); j++)
-        {
-            Component* component = components[j];
+    EditNode* enode = new EditNode();
+    enode->node_ = node;
+    enode->parentBegin_ = enode->parentEnd_ = node->GetParent();
+    node->Serializable::Save(enode->stateBegin_);
+    enode->stateBegin_.Seek(0);
+    enode->stateEnd_ = enode->stateBegin_;
 
-            if (component->IsTemporary())
-                continue;
+    const Vector<SharedPtr<Component>>& components = node->GetComponents();
 
-            EditComponent* ecomponent = new EditComponent();
-            ecomponent->component_ = component;
-            ecomponent->nodeBegin_ = ecomponent->nodeEnd_ = node;
-            component->Serializable::Save(ecomponent->stateBegin_);
-            ecomponent->stateBegin_.Seek(0);
-            ecomponent->stateEnd_ = ecomponent->stateBegin_;
+    for (unsigned j = 0; j < components.Size(); j++)
+    {
+        Component* component = components[j];
 
-            enode->components_.Push(ecomponent);
-        }
+        EditComponent* ecomponent = new EditComponent();
+        ecomponent->component_ = component;
+        ecomponent->nodeBegin_ = ecomponent->nodeEnd_ = node;
+        component->Serializable::Save(ecomponent->stateBegin_);
+        ecomponent->stateBegin_.Seek(0);
+        ecomponent->stateEnd_ = ecomponent->stateBegin_;
+
+        enode->components_.Push(ecomponent);
+    }
+
+    editNodes_.Push(enode);
+
+}
 
-        editNodes_.Push(enode);
+void SelectionEditOp::NodeAdded(Node* node, Node* parent)
+{
+    AddNode(node);
 
+    for (unsigned i = 0; i < editNodes_.Size(); i++)
+    {
+        if (editNodes_[i]->node_ == node)
+        {
+            editNodes_[i]->parentBegin_ = 0;
+            editNodes_[i]->parentEnd_ = parent;
+            return;
+        }
     }
 }
 
-SelectionEditOp::~SelectionEditOp()
+void SelectionEditOp::NodeRemoved(Node* node, Node* parent)
 {
+    AddNode(node);
 
     for (unsigned i = 0; i < editNodes_.Size(); i++)
     {
-        EditNode* enode = editNodes_[i];
-        for (unsigned j = 0; j < enode->components_.Size(); j++)
-            delete enode->components_[j];
-        delete enode;
+        if (editNodes_[i]->node_ == node)
+        {
+            editNodes_[i]->parentBegin_ = parent;
+            editNodes_[i]->parentEnd_ = 0;
+            return;
+        }
     }
+}
+
+void SelectionEditOp::SetNodes(Vector<SharedPtr<Node> > &nodes)
+{
+    // Generate initial snapshot
+    for (unsigned i = 0; i < nodes.Size(); i++)
+    {
+        AddNode(nodes[i]);
 
+    }
 }
 
 bool SelectionEditOp::Commit()
@@ -72,21 +113,15 @@ bool SelectionEditOp::Commit()
         if (enode->parentBegin_ != enode->parentEnd_)
             return true;
 
-        if (enode->stateBegin_.GetSize() != enode->stateEnd_.GetSize() ||
-                memcmp(enode->stateBegin_.GetData(), enode->stateEnd_.GetData(), enode->stateBegin_.GetSize()))
-        {
+        if (!CompareStates(enode->stateBegin_, enode->stateEnd_))
             return true;
-        }
 
         for (unsigned j = 0; j < enode->components_.Size(); j++)
         {
             EditComponent* ecomponent = enode->components_[j];
 
-            if (ecomponent->stateBegin_.GetSize() != ecomponent->stateEnd_.GetSize() ||
-                    memcmp(ecomponent->stateBegin_.GetData(), ecomponent->stateEnd_.GetData(), ecomponent->stateBegin_.GetSize()))
-            {
+            if (!CompareStates(ecomponent->stateBegin_, ecomponent->stateEnd_))
                 return true;
-            }
         }
 
     }
@@ -127,12 +162,20 @@ bool SelectionEditOp::Undo()
 
         Node* node = enode->node_;
 
-        if (!node->Serializable::Load(enode->stateBegin_))
+        bool changed = !CompareStates(enode->stateBegin_, enode->stateEnd_);
+        if (changed && !node->Serializable::Load(enode->stateBegin_))
         {
             LOGERRORF("Unable to Undo node serializable");
             return false;
         }
 
+        if (changed)
+        {
+            VariantMap eventData;
+            eventData[SceneEditStateChange::P_SERIALIZABLE] = node;
+            node->SendEvent(E_SCENEEDITSTATECHANGE, eventData);
+        }
+
         enode->stateBegin_.Seek(0);
 
         if (node->GetParent() != enode->parentBegin_)
@@ -147,12 +190,21 @@ bool SelectionEditOp::Undo()
             EditComponent* ecomponent = enode->components_[j];
             Component* component = ecomponent->component_;
 
-            if (!component->Serializable::Load(ecomponent->stateBegin_))
+            changed = !CompareStates(ecomponent->stateBegin_, ecomponent->stateEnd_);
+            if (changed && !component->Serializable::Load(ecomponent->stateBegin_))
             {
                 LOGERRORF("Unable to Undo component serializable");
                 return false;
             }
 
+            if (changed)
+            {
+                VariantMap eventData;
+                eventData[SceneEditStateChange::P_SERIALIZABLE] = component;
+                component->SendEvent(E_SCENEEDITSTATECHANGE, eventData);
+            }
+
+
             ecomponent->stateBegin_.Seek(0);
 
             if (component->GetNode() != ecomponent->nodeBegin_)
@@ -177,7 +229,8 @@ bool SelectionEditOp::Redo()
 
         Node* node = enode->node_;
 
-        if (!node->Serializable::Load(enode->stateEnd_))
+        bool changed = !CompareStates(enode->stateBegin_, enode->stateEnd_);
+        if ( changed && !node->Serializable::Load(enode->stateEnd_))
         {
             LOGERRORF("Unable to Redo node serializable");
             return false;
@@ -185,6 +238,13 @@ bool SelectionEditOp::Redo()
 
         enode->stateEnd_.Seek(0);
 
+        if (changed)
+        {
+            VariantMap eventData;
+            eventData[SceneEditStateChange::P_SERIALIZABLE] = node;
+            node->SendEvent(E_SCENEEDITSTATECHANGE, eventData);
+        }
+
         if (node->GetParent() != enode->parentEnd_)
         {
             node->Remove();
@@ -197,7 +257,8 @@ bool SelectionEditOp::Redo()
             EditComponent* ecomponent = enode->components_[j];
             Component* component = ecomponent->component_;
 
-            if (!component->Serializable::Load(ecomponent->stateEnd_))
+            changed = !CompareStates(ecomponent->stateBegin_, ecomponent->stateEnd_);
+            if ( changed && !component->Serializable::Load(ecomponent->stateEnd_))
             {
                 LOGERRORF("Unable to Redo component serializable");
                 return false;
@@ -205,6 +266,13 @@ bool SelectionEditOp::Redo()
 
             ecomponent->stateEnd_.Seek(0);
 
+            if (changed)
+            {
+                VariantMap eventData;
+                eventData[SceneEditStateChange::P_SERIALIZABLE] = component;
+                component->SendEvent(E_SCENEEDITSTATECHANGE, eventData);
+            }
+
             if (component->GetNode() != ecomponent->nodeEnd_)
             {
                 component->Remove();

+ 20 - 1
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditOp.h

@@ -38,6 +38,18 @@ public:
     virtual bool Undo() = 0;
     virtual bool Redo() = 0;
 
+    /// Returns true if the states are identical
+    bool CompareStates(const VectorBuffer& stateOne, const VectorBuffer& stateTwo) const
+    {
+        if (stateOne.GetSize() != stateTwo.GetSize())
+            return false;
+
+        if (memcmp(stateOne.GetData(), stateTwo.GetData(), stateOne.GetSize()))
+            return false;
+
+        return true;
+    }
+
     SceneEditType type_;
 
 };
@@ -47,7 +59,7 @@ class SelectionEditOp : public SceneEditOp
 
 public:
 
-    SelectionEditOp(Vector<SharedPtr<Node>>& nodes);
+    SelectionEditOp();
     ~SelectionEditOp();
 
     bool Undo();
@@ -55,6 +67,13 @@ public:
 
     void RegisterEdit();
 
+    void SetNodes(Vector<SharedPtr<Node>>& nodes);
+
+    void AddNode(Node* node);
+
+    void NodeAdded(Node* node, Node* parent);
+    void NodeRemoved(Node* node, Node* parent);
+
     bool Commit();
 
 private:

+ 10 - 0
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditor3DEvents.h

@@ -48,6 +48,16 @@ EVENT(E_SCENEEDITEND, SceneEditEnd)
     PARAM(P_SCENE, Scene);             // Scene
 }
 
+EVENT(E_SCENEEDITSTATECHANGE, SceneEditStateChange)
+{
+    PARAM(P_SERIALIZABLE, Serializable);     // Serializable
+}
+
+EVENT(E_SCENEEDITADDREMOVENODES, SceneEditAddRemoveNodes)
+{
+    PARAM(P_END, End);       // bool
+}
+
 EVENT(E_SCENEEDITSCENEMODIFIED, SceneEditSceneModified)
 {
 

+ 7 - 12
Source/AtomicEditor/Editors/SceneEditor3D/SceneSelection.cpp

@@ -1,4 +1,5 @@
 
+#include <Atomic/IO/Log.h>
 #include <Atomic/Core/CoreEvents.h>
 
 #include <Atomic/Graphics/Graphics.h>
@@ -134,24 +135,18 @@ void SceneSelection::Delete()
 
     Clear();
 
+    VariantMap eventData;
+    eventData[SceneEditAddRemoveNodes::P_END] = false;
+    scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
+
     for (unsigned i = 0; i < nodes.Size(); i++)
     {
         nodes[i]->Remove();
     }
 
-    /*
-    if (selectedNode_)
-    {
-        VariantMap editData;
-        editData[SceneEditNodeAddedRemoved::P_SCENE] = scene_;
-        editData[SceneEditNodeAddedRemoved::P_NODE] = selectedNode_;
-        editData[SceneEditNodeAddedRemoved::P_ADDED] = false;
-        scene_->SendEvent(E_SCENEEDITNODEADDEDREMOVED, editData);
+    eventData[SceneEditAddRemoveNodes::P_END] = true;
+    scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
 
-        selectedNode_->Remove();
-        selectedNode_ = 0;
-    }
-    */
 }
 
 void SceneSelection::GetBounds(BoundingBox& bbox)