|
|
@@ -16,16 +16,9 @@ namespace AtomicEditor
|
|
|
|
|
|
SceneEditHistory::SceneEditHistory(Context* context, Scene* scene) :
|
|
|
Object(context),
|
|
|
- scene_(scene),
|
|
|
- locked_(false)
|
|
|
+ scene_(scene)
|
|
|
{
|
|
|
- SubscribeToEvent(E_HISTORYNODEADDED, HANDLER(SceneEditHistory, HandleHistoryNodeAdded));
|
|
|
- SubscribeToEvent(E_HISTORYNODEREMOVED, HANDLER(SceneEditHistory, HandleHistoryNodeRemoved));
|
|
|
- SubscribeToEvent(E_HISTORYNODECHANGED, HANDLER(SceneEditHistory, HandleHistoryNodeChanged));
|
|
|
-
|
|
|
- SubscribeToEvent(E_HISTORYCOMPONENTCHANGED, HANDLER(SceneEditHistory, HandleHistoryComponentChanged));
|
|
|
-
|
|
|
- SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditHistory, HandleEditorActiveNodeChange));
|
|
|
+ SubscribeToEvent(scene_, E_SCENEEDITSERIALIZABLE, HANDLER(SceneEditHistory, HandleSceneEditSerializable));
|
|
|
}
|
|
|
|
|
|
SceneEditHistory::~SceneEditHistory()
|
|
|
@@ -33,151 +26,73 @@ SceneEditHistory::~SceneEditHistory()
|
|
|
|
|
|
}
|
|
|
|
|
|
-void SceneEditHistory::AddUndoOp(SceneHistoryOp* op)
|
|
|
+void SceneEditHistory::AddUndoOp(SceneEditOp* op)
|
|
|
{
|
|
|
undoHistory_.Push(op);
|
|
|
|
|
|
- // adding a new undo op invalids redos
|
|
|
for (unsigned i = 0; i < redoHistory_.Size(); i++)
|
|
|
{
|
|
|
delete redoHistory_[i];
|
|
|
}
|
|
|
|
|
|
redoHistory_.Clear();
|
|
|
-
|
|
|
- if (activeNode_.NotNull())
|
|
|
- {
|
|
|
- if (op->type_ == SCENEHISTORYOP_NODECHANGED)
|
|
|
- {
|
|
|
- activeNodeCurrentState_.Clear();
|
|
|
- activeNode_->Animatable::Save(activeNodeCurrentState_);
|
|
|
- activeNodeCurrentState_.Seek(0);
|
|
|
- }
|
|
|
-
|
|
|
- if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
|
|
|
- {
|
|
|
- ComponentChangedOp* ccop = (ComponentChangedOp*) op;
|
|
|
- currentComponentStates_[ccop->component_].Clear();
|
|
|
- ccop->component_->Animatable::Save(currentComponentStates_[ccop->component_]);
|
|
|
- currentComponentStates_[ccop->component_].Seek(0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-void SceneEditHistory::HandleHistoryNodeAdded(StringHash eventType, VariantMap& eventData)
|
|
|
+void SceneEditHistory::HandleSceneEditSerializableUndoRedo(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
- if (locked_)
|
|
|
- return;
|
|
|
-
|
|
|
- Scene* scene = static_cast<Scene*>(eventData[HistoryNodeAdded::P_SCENE].GetPtr());
|
|
|
- if (scene != scene_)
|
|
|
- return;
|
|
|
+ SharedPtr<Serializable> serial(static_cast<Serializable*>(eventData[SceneEditSerializableUndoRedo::P_SERIALIZABLE].GetPtr()));
|
|
|
|
|
|
- Node* node = static_cast<Node*>(eventData[HistoryNodeAdded::P_NODE].GetPtr());
|
|
|
-
|
|
|
- NodeAddedOp* op = new NodeAddedOp(node);
|
|
|
- AddUndoOp(op);
|
|
|
-}
|
|
|
-
|
|
|
-void SceneEditHistory::HandleHistoryNodeChanged(StringHash eventType, VariantMap& eventData)
|
|
|
-{
|
|
|
- if (locked_)
|
|
|
- return;
|
|
|
-
|
|
|
- Scene* scene = static_cast<Scene*>(eventData[HistoryNodeChanged::P_SCENE].GetPtr());
|
|
|
-
|
|
|
- if (scene != scene_)
|
|
|
- return;
|
|
|
-
|
|
|
- Node* node = static_cast<Node*>(eventData[HistoryNodeChanged::P_NODE].GetPtr());
|
|
|
-
|
|
|
- NodeChangedOp* op = new NodeChangedOp(node, activeNodeCurrentState_);
|
|
|
-
|
|
|
- if (activeNodeCurrentState_.GetSize() != op->newState_.GetSize() ||
|
|
|
- memcmp(activeNodeCurrentState_.GetData(), op->newState_.GetData(), op->newState_.GetSize()))
|
|
|
- {
|
|
|
- activeNodeCurrentState_ = op->newState_;
|
|
|
- AddUndoOp(op);
|
|
|
- }
|
|
|
- else
|
|
|
+ if (editStates_.Contains(serial))
|
|
|
{
|
|
|
- delete op;
|
|
|
+ editStates_[serial] = eventData[SceneEditSerializableUndoRedo::P_STATE].GetVectorBuffer();
|
|
|
}
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-void SceneEditHistory::HandleHistoryNodeRemoved(StringHash eventType, VariantMap& eventData)
|
|
|
-{
|
|
|
- if (locked_)
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
-void SceneEditHistory::HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData)
|
|
|
+void SceneEditHistory::HandleSceneEditSerializable(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
- Node* node = static_cast<Node*>(eventData[EditorActiveNodeChange::P_NODE].GetPtr());
|
|
|
-
|
|
|
- if (activeNode_ == node)
|
|
|
- return;
|
|
|
|
|
|
- activeNode_ = node;
|
|
|
- activeNodeCurrentState_.Clear();
|
|
|
- currentComponentStates_.Clear();
|
|
|
+ int editop = eventData[SceneEditSerializable::P_OPERATION].GetInt();
|
|
|
|
|
|
- if (activeNode_.Null())
|
|
|
- return;
|
|
|
+ SharedPtr<Serializable> serial(static_cast<Serializable*>(eventData[SceneEditSerializable::P_SERIALIZABLE].GetPtr()));
|
|
|
|
|
|
- node->Animatable::Save(activeNodeCurrentState_);
|
|
|
- activeNodeCurrentState_.Seek(0);
|
|
|
-
|
|
|
- const Vector<SharedPtr<Component> >& comps = activeNode_->GetComponents();
|
|
|
- for (unsigned i = 0; i < comps.Size(); i++)
|
|
|
+ if (editop == 0) // begin
|
|
|
{
|
|
|
- comps[i]->Animatable::Save(currentComponentStates_[comps[i]]);
|
|
|
- currentComponentStates_[comps[i]].Seek(0);
|
|
|
+ if (editStates_.Contains(serial))
|
|
|
+ return;
|
|
|
+
|
|
|
+ SubscribeToEvent(serial, E_SCENEEDITSERIALIZABLEUNDOREDO, HANDLER(SceneEditHistory, HandleSceneEditSerializableUndoRedo));
|
|
|
+ VectorBuffer& vb = editStates_[serial];
|
|
|
+ vb.Clear();
|
|
|
+ serial->Serializable::Save(vb);
|
|
|
+ vb.Seek(0);
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-void SceneEditHistory::HandleHistoryComponentChanged(StringHash eventType, VariantMap& eventData)
|
|
|
-{
|
|
|
- if (locked_)
|
|
|
- return;
|
|
|
-
|
|
|
- Component* component = static_cast<Component*>(eventData[HistoryComponentChanged::P_COMPONENT].GetPtr());
|
|
|
-
|
|
|
- if (!component || component->GetNode() != activeNode_)
|
|
|
- return;
|
|
|
-
|
|
|
- assert(currentComponentStates_.Contains(component));
|
|
|
+ else if (editop == 1) // change
|
|
|
+ {
|
|
|
+ if (!editStates_.Contains(serial))
|
|
|
+ return;
|
|
|
|
|
|
- ComponentChangedOp* op = new ComponentChangedOp(component, currentComponentStates_[component]);
|
|
|
+ VectorBuffer& beginState = editStates_[serial];
|
|
|
+ VectorBuffer deltaState;
|
|
|
+ serial->Serializable::Save(deltaState);
|
|
|
+ deltaState.Seek(0);
|
|
|
|
|
|
- if (currentComponentStates_[component].GetSize() != op->newState_.GetSize() ||
|
|
|
- memcmp(currentComponentStates_[component].GetData(), op->newState_.GetData(), op->newState_.GetSize()))
|
|
|
- {
|
|
|
- activeNodeCurrentState_ = op->newState_;
|
|
|
- AddUndoOp(op);
|
|
|
+ if (beginState.GetSize() != deltaState.GetSize() ||
|
|
|
+ memcmp(beginState.GetData(), deltaState.GetData(), deltaState.GetSize()))
|
|
|
+ {
|
|
|
+ SerializableEditOp* op = new SerializableEditOp(serial, beginState, deltaState);
|
|
|
+ AddUndoOp(op);
|
|
|
+ editStates_[serial] = deltaState;
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+ else if (editop == 2) // end
|
|
|
{
|
|
|
- delete op;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
+ if (!editStates_.Contains(serial))
|
|
|
+ return;
|
|
|
|
|
|
-void SceneEditHistory::BeginUndoRedo()
|
|
|
-{
|
|
|
- //VariantMap evData;
|
|
|
- //evData[SceneUndoRedoBegin::P_SCENE] = scene_;
|
|
|
- //SendEvent(E_SCENEUNDOREDOBEGIN, evData);
|
|
|
-}
|
|
|
+ UnsubscribeFromEvent(serial, E_SCENEEDITSERIALIZABLEUNDOREDO);
|
|
|
|
|
|
-void SceneEditHistory::EndUndoRedo()
|
|
|
-{
|
|
|
- //VariantMap evData;
|
|
|
- //evData[SceneUndoRedoEnd::P_SCENE] = scene_;
|
|
|
- //SendEvent(E_SCENEUNDOREDOEND, evData);
|
|
|
+ editStates_.Erase(serial);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void SceneEditHistory::Undo()
|
|
|
@@ -185,26 +100,13 @@ void SceneEditHistory::Undo()
|
|
|
if (!undoHistory_.Size())
|
|
|
return;
|
|
|
|
|
|
- SceneHistoryOp* op = undoHistory_.Back();
|
|
|
+ SceneEditOp* op = undoHistory_.Back();
|
|
|
undoHistory_.Pop();
|
|
|
|
|
|
op->Undo();
|
|
|
|
|
|
- VariantMap eventData;
|
|
|
- if (op->type_ == SCENEHISTORYOP_NODECHANGED)
|
|
|
- {
|
|
|
- NodeChangedOp* ncop = (NodeChangedOp*) op;
|
|
|
- eventData[HistoryNodeChangedUndoRedo::P_NODE] = ncop->node_;
|
|
|
- ncop->node_->SendEvent(E_HISTORYNODECHANGEDUNDOREDO, eventData);
|
|
|
- }
|
|
|
- else if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
|
|
|
- {
|
|
|
- ComponentChangedOp* ccop = (ComponentChangedOp*) op;
|
|
|
- eventData[HistoryComponentChangedUndoRedo::P_COMPONENT] = ccop->component_;
|
|
|
- ccop->component_->SendEvent(E_HISTORYCOMPONENTCHANGEDUNDOREDO, eventData);
|
|
|
- }
|
|
|
-
|
|
|
redoHistory_.Push(op);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
void SceneEditHistory::Redo()
|
|
|
@@ -212,29 +114,13 @@ void SceneEditHistory::Redo()
|
|
|
if (!redoHistory_.Size())
|
|
|
return;
|
|
|
|
|
|
- SceneHistoryOp* op = redoHistory_.Back();
|
|
|
+ SceneEditOp* op = redoHistory_.Back();
|
|
|
redoHistory_.Pop();
|
|
|
|
|
|
op->Redo();
|
|
|
|
|
|
undoHistory_.Push(op);
|
|
|
|
|
|
- VariantMap eventData;
|
|
|
- if (op->type_ == SCENEHISTORYOP_NODECHANGED)
|
|
|
- {
|
|
|
- NodeChangedOp* ncop = (NodeChangedOp*) op;
|
|
|
- eventData[HistoryNodeChangedUndoRedo::P_NODE] = ncop->node_;
|
|
|
- ncop->node_->SendEvent(E_HISTORYNODECHANGEDUNDOREDO, eventData);
|
|
|
- }
|
|
|
- else if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
|
|
|
- {
|
|
|
- ComponentChangedOp* ccop = (ComponentChangedOp*) op;
|
|
|
- eventData[HistoryComponentChangedUndoRedo::P_COMPONENT] = ccop->component_;
|
|
|
- ccop->component_->SendEvent(E_HISTORYCOMPONENTCHANGEDUNDOREDO, eventData);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
}
|