Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / r2 / dmc / action_historic.cpp
blobcab232895c1824952f5b07dfd86501ff29890b0b
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
21 #include "action_historic.h"
22 #include "property_accessor.h"
23 #include "../object_factory_client.h"
24 #include "../editor.h"
25 #include "nel/gui/lua_ihm.h"
27 #ifdef DEBUG_NEW
28 #define new DEBUG_NEW
29 #endif
31 namespace R2
34 /////////////////////
35 // CActionHistoric //
36 /////////////////////
39 //====================================================================================
40 CActionHistoric::CActionHistoric() : _Scenario(NULL, st_edit)
42 _NewActionIsPending = false;
43 _CurrActionIndex = -1;
44 setMaxNumActions(50);
45 _SubActionCount = 0;
48 //====================================================================================
49 CActionHistoric::~CActionHistoric()
53 //====================================================================================
54 void CActionHistoric::newSingleAction(const ucstring &name)
56 //H_AUTO(R2_CActionHistoric_newSingleAction)
57 endAction();
58 if (_SubActionCount == 0)
60 _SubActionCount = 1;
61 _NewActionIsPending = false;
63 if (!_NewActionIsPending)
65 _NewActionName = name;
69 //====================================================================================
70 void CActionHistoric::cancelAction()
72 //H_AUTO(R2_CActionHistoric_cancelAction)
73 if (_NewAction && _NewActionIsPending)
75 _NewAction->rollback(_DMC, _Scenario);
77 _NewAction = NULL;
78 _NewActionIsPending = false;
79 _SubActionCount = 1;
80 _NewActionName.clear();
81 getEditor().callEnvMethod("onCancelActionInHistoric", 0, 0);
84 //====================================================================================
85 void CActionHistoric::newMultiAction(const ucstring &name, uint actionCount)
87 //H_AUTO(R2_CActionHistoric_newMultiAction)
88 _SubActionCount = 1; // force previous multi action to finish
89 endAction();
90 _NewActionIsPending = false;
91 _SubActionCount = actionCount;
92 _NewActionName = name;
95 //====================================================================================
96 void CActionHistoric::flushPendingAction()
98 //H_AUTO(R2_CActionHistoric_flushPendingAction)
99 if (_NewAction && _NewActionIsPending)
101 _NewAction->flush(_DMC, _Scenario);
105 //====================================================================================
106 void CActionHistoric::newPendingMultiAction(const ucstring &name, uint actionCount)
108 //H_AUTO(R2_CActionHistoric_newPendingMultiAction)
109 _SubActionCount = 1; // force previous multi action to finish
110 endAction();
111 _NewActionIsPending = true;
112 _SubActionCount = actionCount;
113 _NewActionName = name;
114 getEditor().callEnvMethod("onPendingActionBegin", 0, 0);
117 //====================================================================================
118 void CActionHistoric::newPendingAction(const ucstring &name)
120 //H_AUTO(R2_CActionHistoric_newPendingAction)
121 endAction();
122 _NewActionIsPending = true;
123 _NewActionName = name;
124 getEditor().callEnvMethod("onPendingActionBegin", 0, 0);
127 //====================================================================================
128 void CActionHistoric::endAction()
130 //H_AUTO(R2_CActionHistoric_endAction)
131 // if current action is void, no-op
132 if (!_NewAction)
134 return;
137 if (_SubActionCount == 0)
139 return;
141 -- _SubActionCount;
142 if (_SubActionCount > 0)
144 return; // several actions expected before the merge
146 ++_CurrActionIndex;
147 // Push the new action -> discard all actions beyond _CurrActionIndex
148 uint newSize = (uint) std::max((sint) _Actions.getSize() + _CurrActionIndex, 0);
149 while (_Actions.getSize() > newSize)
151 _Actions.pop();
153 _CurrActionIndex = -1;
154 _Actions.push(_NewAction);
155 if (!_NewActionIsPending)
157 _NewAction->flush(_DMC, _Scenario); // redo may trigger other observers that complete the action
159 _NewAction->setCompleted();
160 _CurrActionIndex = -1;
161 _NewAction = NULL;
162 _NewActionIsPending = false;
163 // warn lua that a new action has been added
164 if (isUndoSupported())
166 getEditor().callEnvMethod("onNewActionAddedInHistoric", 0, 0);
170 //====================================================================================
171 void CActionHistoric::forceEndMultiAction()
173 //H_AUTO(R2_CActionHistoric_forceEndMultiAction)
174 if (_NewActionIsPending && _NewAction)
176 _NewAction->flush(_DMC, _Scenario);
178 if (_SubActionCount > 1) _SubActionCount = 1;
179 endAction();
182 //====================================================================================
183 void CActionHistoric::setMaxNumActions(uint count)
185 //H_AUTO(R2_CActionHistoric_setMaxNumActions)
186 nlassert(count >= 1);
187 _Actions.setMaxSize(count);
190 //====================================================================================
191 void CActionHistoric::clear(CObject *newScenario)
193 //H_AUTO(R2_CActionHistoric_clear)
194 if (_NewActionIsPending)
196 nlwarning("Historic was cleared while a pending action!!");
198 _Actions.clear();
199 _CurrActionIndex = -1;
200 _NewAction = NULL;
201 _NewActionIsPending = false;
202 _Scenario.setHighLevel(newScenario ? CRequestBase::cloneObject(newScenario) : NULL);
203 // warn lua that all actions have been cleared
204 getEditor().callEnvMethod("onClearActionHistoric", 0, 0);
208 //====================================================================================
209 sint CActionHistoric::getPreviousActionIndex() const
211 //H_AUTO(R2_CActionHistoric_getPreviousActionIndex)
212 sint index = (sint) _Actions.getSize() + _CurrActionIndex;
213 return index >= 0 ? index : -1;
216 //====================================================================================
217 sint CActionHistoric::getNextActionIndex() const
219 //H_AUTO(R2_CActionHistoric_getNextActionIndex)
220 if (_Actions.empty()) return -1;
221 sint index = (sint) _Actions.getSize() + (_CurrActionIndex + 1);
222 return index >= 0 && index < (sint) _Actions.getSize() ? index : -1;
225 //====================================================================================
226 bool CActionHistoric::canUndo() const
228 //H_AUTO(R2_CActionHistoric_canUndo)
229 if (_NewActionIsPending) return false;
230 return getPreviousActionIndex() != -1;
233 //====================================================================================
234 bool CActionHistoric::canRedo() const
236 //H_AUTO(R2_CActionHistoric_canRedo)
237 if (_NewActionIsPending) return false;
238 return getNextActionIndex() != -1;
241 //====================================================================================
242 bool CActionHistoric::undo()
244 //H_AUTO(R2_CActionHistoric_undo)
245 nlassert(!_NewActionIsPending);
246 sint index = getPreviousActionIndex();
247 if (index == -1) return false;
248 _Actions[index]->undo(_DMC, _Scenario);
249 -- _CurrActionIndex;
250 return true;
253 //====================================================================================
254 bool CActionHistoric::redo()
256 //H_AUTO(R2_CActionHistoric_redo)
257 nlassert(!_NewActionIsPending);
258 sint index = getNextActionIndex();
259 if (index == -1) return false;
260 _Actions[index]->redo(_DMC, _Scenario);
261 ++ _CurrActionIndex;
262 return true;
265 //====================================================================================
266 const ucstring *CActionHistoric::getPreviousActionName() const
268 //H_AUTO(R2_CActionHistoric_getPreviousActionName)
269 sint index = getPreviousActionIndex();
270 return index != -1 ? &_Actions[index]->getName() : NULL;
273 //====================================================================================
274 const ucstring *CActionHistoric::getNextActionName() const
276 //H_AUTO(R2_CActionHistoric_getNextActionName)
277 sint index = getNextActionIndex();
278 return index != -1 ? &_Actions[index]->getName() : NULL;
281 //====================================================================================
282 void CActionHistoric::requestInsertNode(const std::string& instanceId, const std::string& name,sint32 position, const std::string& key, CObject* value)
284 //H_AUTO(R2_CActionHistoric_requestInsertNode)
285 if (_Scenario.getHighLevel())
287 CObject *target = _DMC->find(instanceId, name);
288 if (value->getGhost() || (target && target->getGhost()))
290 // direct effect, assumed to be local display only
291 getEditor().getDMC().nodeInserted(instanceId, name, position, key, value->clone());
292 return;
295 if (!_NewAction) _NewAction = new CAction(_NewActionName);
296 CRequestBase::TSmartPtr req = new CRequestInsertNode(instanceId, name, position, key, value);
297 //if (_NewActionIsPending) req->redo(_DMC, _Scenario);
298 _NewAction->pushRequest(req);
301 //====================================================================================
302 void CActionHistoric::requestSetNode(const std::string& instanceId,const std::string& attrName, CObject* value)
304 //H_AUTO(R2_CActionHistoric_requestSetNode)
305 if (_Scenario.getHighLevel())
307 CObject *clObj = _DMC->find(instanceId, attrName);
308 if (clObj && clObj->getGhost())
310 value->setGhost(true);
312 if (value->getGhost())
314 // direct effect, assumed to be local display only
315 getEditor().getDMC().nodeSet(instanceId, attrName, value->clone());
316 return;
319 if (!_NewAction) _NewAction = new CAction(_NewActionName);
320 CRequestBase::TSmartPtr req = new CRequestSetNode(instanceId, attrName, value);
321 //if (_NewActionIsPending) req->redo(_DMC, _Scenario);
322 _NewAction->pushRequest(req);
325 //====================================================================================
326 void CActionHistoric::requestEraseNode(const std::string& instanceId, const std::string& attrName, sint32 position)
328 //H_AUTO(R2_CActionHistoric_requestEraseNode)
329 if (_Scenario.getHighLevel())
331 CObject *obj = _DMC->find(instanceId, attrName, position);
332 if (obj && obj->getGhost())
334 // direct effect, assumed to be local display only
335 getEditor().getDMC().nodeErased(instanceId, attrName, position);
336 return;
339 if (!_NewAction) _NewAction = new CAction(_NewActionName);
340 CRequestBase::TSmartPtr req = new CRequestEraseNode(instanceId, attrName, position);
341 //if (_NewActionIsPending) req->redo(_DMC, _Scenario);
342 _NewAction->pushRequest(req);
345 //====================================================================================
346 void CActionHistoric::requestMoveNode(const std::string& instanceId, const std::string& attrName, sint32 position, const std::string& destInstanceId, const std::string& destAttrName, sint32 destPosition)
348 //H_AUTO(R2_CActionHistoric_requestMoveNode)
349 if (_Scenario.getHighLevel())
351 CObject *src = _DMC->find(instanceId, attrName, position);
352 CObject *dest = _DMC->find(destInstanceId, destAttrName);
353 if (src && dest)
355 nlassert(src->getGhost() == dest->getGhost());
356 if (src->getGhost())
358 // direct effect, assumed to be local display only
359 getEditor().getDMC().nodeMoved(instanceId, attrName, position, destInstanceId, destAttrName, destPosition);
360 return;
364 if (!_NewAction) _NewAction = new CAction(_NewActionName);
365 CRequestBase::TSmartPtr req = new CRequestMoveNode(instanceId, attrName, position, destInstanceId, destAttrName, destPosition);
366 //if (_NewActionIsPending) req->redo(_DMC, _Scenario);
367 _NewAction->pushRequest(req);
370 /////////////
371 // CAction //
372 /////////////
375 //====================================================================================
376 CActionHistoric::CAction::CAction(const ucstring &name) : _Name(name), _FlushedCount(0), _Completed(false), _Flushing(false)
380 //====================================================================================
381 void CActionHistoric::CAction::pushRequest(CRequestBase *req)
383 //H_AUTO(R2_CAction_pushRequest)
384 nlassert(req);
385 nlassert(!_Completed);
386 _Requests.push_back(req);
390 //====================================================================================
391 CActionHistoric::CAction::~CAction()
395 //====================================================================================
396 void CActionHistoric::CAction::flush(IDynamicMapClient *dmc, CScenario &scenario)
398 //H_AUTO(R2_CAction_flush)
399 nlwarning("Flushing action at 0x%p", this);
400 if (_Flushing) return;
401 _Flushing = true;
402 nlassert(_FlushedCount <= _Requests.size());
403 nlassert(!_Completed);
404 while (_FlushedCount != _Requests.size())
406 _Requests[_FlushedCount]->redo(dmc, scenario);
407 ++ _FlushedCount;
408 nlassert(_FlushedCount <= _Requests.size());
410 nlassert(_FlushedCount == _Requests.size());
411 _Flushing = false;
414 //====================================================================================
415 void CActionHistoric::CAction::rollback(IDynamicMapClient *dmc, CScenario &scenario)
417 //H_AUTO(R2_CAction_rollback)
418 nlassert(_FlushedCount <= _Requests.size());
419 for (sint k = _FlushedCount - 1; k >= 0; --k)
421 _Requests[k]->undo(dmc, scenario);
423 _FlushedCount = 0;
426 //====================================================================================
427 void CActionHistoric::CAction::redo(IDynamicMapClient *dmc, CScenario &scenario)
429 //H_AUTO(R2_CAction_redo)
430 nlassert(_FlushedCount <= _Requests.size());
431 nlassert(_Completed);
432 nlassert(dmc);
433 for (uint k = 0; k < _Requests.size(); ++k)
435 _Requests[k]->redo(dmc, scenario);
439 //====================================================================================
440 void CActionHistoric::CAction::undo(IDynamicMapClient *dmc, CScenario &scenario)
442 //H_AUTO(R2_CAction_undo)
443 nlassert(_FlushedCount <= _Requests.size());
444 nlassert(_Completed);
445 nlassert(dmc);
446 for (sint k = (sint)_Requests.size() - 1; k >= 0; --k)
448 _Requests[k]->undo(dmc, scenario);
452 //////////////
453 // REQUESTS //
454 //////////////
456 //====================================================================================
457 CObject *CActionHistoric::CRequestBase::cloneObject(const CObject *src)
459 //H_AUTO(R2_CRequestBase_cloneObject)
460 CObject *result = src->clone();
461 struct CDisableRefIDs : public IObjectVisitor
463 virtual void visit(CObjectRefId &obj)
465 CObjectRefIdClient *refId = NLMISC::safe_cast<CObjectRefIdClient *>(&obj);
466 refId->enable(false); // disable events
469 CDisableRefIDs disableRefIDs;
470 result->visit(disableRefIDs);
471 return result;
474 //====================================================================================
475 CActionHistoric::CRequestSetNode::CRequestSetNode(const std::string &instanceId,
476 const std::string& attrName,
477 CObject* value)
479 nlassert(value);
480 _InstanceId = instanceId;
481 _AttrName = attrName;
482 _NewValue = cloneObject(value);
485 void CActionHistoric::CRequestSetNode::redo(IDynamicMapClient *dmc, CScenario &scenario)
487 //H_AUTO(R2_CRequestSetNode_redo)
488 _OldValue = NULL;
489 if (scenario.getHighLevel()) // undo allowed ?
491 CObject *old = scenario.find(_InstanceId, _AttrName);
492 if (old) // may be not found if defined in the base and not redefined yet
494 // maybe a shadowed property ?
495 /*CObject *shadow = dmc->getPropertyAccessor().getShadowingValue(old);
496 if (shadow) old = shadow; // use the shadow instead*/
497 _OldValue = cloneObject(old);
498 nlwarning("**** backupped value for undo request set node");
499 _OldValue->dump();
501 // modify local version
502 scenario.setNode(_InstanceId, _AttrName, _NewValue);
504 // send to network
505 dmc->doRequestSetNode(_InstanceId, _AttrName, _NewValue);
508 void CActionHistoric::CRequestSetNode::undo(IDynamicMapClient *dmc, CScenario &scenario)
510 //H_AUTO(R2_CRequestSetNode_undo)
511 nlassert(scenario.getHighLevel()); // if this assert fires, then 'clear' was called with a NULL pointer ! The action historic need a start scenario to have undo capability
512 if (!_OldValue)
514 // was a value from the base ? just erase ...
516 // modify local version
517 scenario.eraseNode(_InstanceId, _AttrName, -1);
518 // send to network
519 dmc->doRequestEraseNode(_InstanceId, _AttrName, -1);
521 else
523 // modify local version
524 scenario.setNode(_InstanceId, _AttrName, _OldValue);
525 // send to network
526 // TODO nico : handle case where same value than the base is restored here
527 dmc->doRequestSetNode(_InstanceId, _AttrName, _OldValue);
530 _OldValue = NULL;
532 //====================================================================================
533 CActionHistoric::CRequestEraseNode::CRequestEraseNode(const std::string& instanceId, const std::string& attrName, sint32 position)
535 //H_AUTO(R2_CRequestEraseNode_CRequestEraseNode)
536 _InstanceId = instanceId;
537 _AttrName = attrName;
538 _Position = position;
541 void CActionHistoric::CRequestEraseNode::redo(IDynamicMapClient *dmc, CScenario &scenario)
543 //H_AUTO(R2_CRequestEraseNode_redo)
544 nlassert(dmc);
545 _OldValue = NULL;
546 if (scenario.getHighLevel()) // undo allowed ?
548 CObject *old = scenario.find(_InstanceId, _AttrName, _Position);
549 if (!old)
551 nlwarning("Can't redo erase request!!");
552 nlassert(0); // TMP TMP
553 return;
555 if (!old->getNameInParent(_ParentInstanceId, _AttrNameInParent, _PositionInParent))
557 nlwarning("Can't retrieve name in parent, requestEraseNode undo will fail!");
559 _OldValue = cloneObject(old);
561 // modify local version
562 scenario.eraseNode(_InstanceId, _AttrName, _Position);
564 // send to network
565 dmc->doRequestEraseNode(_InstanceId, _AttrName, _Position);
568 void CActionHistoric::CRequestEraseNode::undo(IDynamicMapClient *dmc, CScenario &scenario)
570 //H_AUTO(R2_CRequestEraseNode_undo)
571 nlassert(scenario.getHighLevel()); // if this assert fires, then 'clear' was called with a NULL pointer ! The action historic need a start scenario to have undo capability
572 nlassert(dmc);
573 if (!_OldValue)
575 nlwarning("Can't undo erase node, previous node not saved");
576 return;
578 if (_ParentInstanceId.empty())
580 nlwarning("Can't undo erase node, parent name not known");
581 return;
583 // modify local version
584 scenario.insertNode(_ParentInstanceId, _AttrNameInParent, _PositionInParent, "", cloneObject(_OldValue));
585 // send to network
586 dmc->doRequestInsertNode(_ParentInstanceId, _AttrNameInParent, _PositionInParent, "", _OldValue);
587 _OldValue = NULL;
589 #ifdef RYZOM_LUA_UCSTRING
590 CLuaIHM::push(getEditor().getLua(), ucstring::makeFromUtf8(_InstanceId));
591 #else
592 getEditor().getLua().push(_InstanceId);
593 #endif
594 getEditor().callEnvMethod("setUndoRedoInstances", 1, 0);
596 //====================================================================================
597 CActionHistoric::CRequestInsertNode::CRequestInsertNode(const std::string& instanceId,
598 const std::string &attrName,
599 sint32 position,
600 const std::string& key,
601 CObject* value)
603 _InstanceId = instanceId;
604 _AttrName = attrName;
605 _Position = position;
606 _Key = key;
607 _Value = cloneObject(value);
610 void CActionHistoric::CRequestInsertNode::redo(IDynamicMapClient *dmc, CScenario &scenario)
612 //H_AUTO(R2_CRequestInsertNode_redo)
613 nlassert(dmc);
614 if (scenario.getHighLevel())
616 // modify local version
617 scenario.insertNode(_InstanceId, _AttrName, _Position, _Key, cloneObject(_Value));
619 // send to network
620 dmc->doRequestInsertNode(_InstanceId, _AttrName, _Position, _Key, _Value);
622 CObject* nodeId = _Value->findAttr("InstanceId");
623 #ifdef RYZOM_LUA_UCSTRING
624 CLuaIHM::push(getEditor().getLua(), ucstring::makeFromUtf8(nodeId->toString()));
625 #else
626 getEditor().getLua().push(nodeId->toString());
627 #endif
628 getEditor().callEnvMethod("setUndoRedoInstances", 1, 0);
631 void CActionHistoric::CRequestInsertNode::undo(IDynamicMapClient *dmc, CScenario &scenario)
633 //H_AUTO(R2_CRequestInsertNode_undo)
634 nlassert(scenario.getHighLevel()); // if this assert fires, then 'clear' was called with a NULL pointer ! The action historic need a start scenario to have undo capability
635 nlassert(dmc);
636 // if there's a key here, not good for us :(
637 // so try to find another shorter name for this object...
638 if (!_Key.empty())
640 std::string instanceId;
641 std::string attrName;
642 sint32 position;
643 CObject *currObj = scenario.find(_InstanceId, _AttrName, _Position, _Key);
644 if (!currObj) return;
645 if (currObj->getShortestName(instanceId, attrName, position))
647 // modify local version
648 scenario.eraseNode(instanceId, attrName, position);
649 // send to network
650 dmc->doRequestEraseNode(instanceId, attrName, position);
652 #ifdef RYZOM_LUA_UCSTRING
653 CLuaIHM::push(getEditor().getLua(), ucstring::makeFromUtf8(instanceId));
654 #else
655 getEditor().getLua().push(instanceId);
656 #endif
657 getEditor().callEnvMethod("setUndoRedoInstances", 1, 0);
659 else
661 nlassert(0); // TMP : can this really happen in practice ?
662 nlwarning("Can't build request insert node reciprocal");
665 else
667 // special here : if position is -1, requestEraseNode will erase the
668 // table, not the last element!
669 if (!_AttrName.empty() && _Position == -1)
671 CObject *parentTable = scenario.find(_InstanceId, _AttrName);
672 if (parentTable && parentTable->isTable())
674 uint index = parentTable->getSize() - 1;
675 // modify local version
676 scenario.eraseNode(_InstanceId, _AttrName, index);
677 // send to network
678 dmc->doRequestEraseNode(_InstanceId, _AttrName, index);
681 else
683 // modify local version
684 scenario.eraseNode(_InstanceId, _AttrName, _Position);
685 // send to network
686 dmc->doRequestEraseNode(_InstanceId, _AttrName, _Position);
690 //====================================================================================
691 CActionHistoric::CRequestMoveNode::CRequestMoveNode(const std::string &srcInstanceId,
692 const std::string &srcAttrName,
693 sint32 srcPosition,
694 const std::string &destInstanceId,
695 const std::string &destAttrName,
696 sint32 destPosition)
698 _SrcInstanceId = srcInstanceId;
699 _SrcAttrName = srcAttrName;
700 _SrcPosition = srcPosition;
701 _DestInstanceId = destInstanceId;
702 _DestAttrName = destAttrName;
703 _DestPosition = destPosition;
706 void CActionHistoric::CRequestMoveNode::redo(IDynamicMapClient *dmc, CScenario &scenario)
708 //H_AUTO(R2_CRequestMoveNode_redo)
709 nlassert(dmc);
710 if (scenario.getHighLevel())
712 CObject *src = scenario.find(_SrcInstanceId, _SrcAttrName, _SrcPosition);
713 if (!src)
715 nlwarning("Can't find source when moving node");
716 return;
718 if (!src->getNameInParent(_SrcInstanceIdInParent, _SrcAttrNameInParent, _SrcPositionInParent))
720 nlwarning("Can't find name of source object in its parent");
721 return;
723 // modify local version
724 scenario.moveNode(_SrcInstanceId,
725 _SrcAttrName,
726 _SrcPosition,
727 _DestInstanceId,
728 _DestAttrName,
729 _DestPosition);
730 if (!src->getShortestName(_DestInstanceIdAfterMove, _DestAttrNameAfterMove, _DestPositionAfterMove))
732 nlwarning("Can't retrieve name of instance after move, undo will fail");
735 // send to network
736 dmc->doRequestMoveNode(_SrcInstanceId,
737 _SrcAttrName,
738 _SrcPosition,
739 _DestInstanceId,
740 _DestAttrName,
741 _DestPosition);
744 void CActionHistoric::CRequestMoveNode::undo(IDynamicMapClient *dmc, CScenario &scenario)
746 //H_AUTO(R2_CRequestMoveNode_undo)
747 nlassert(scenario.getHighLevel()); // if this assert fires, then 'clear' was called with a NULL pointer ! The action historic need a start scenario to have undo capability
748 nlassert(dmc);
749 // modify local version
750 scenario.moveNode(_DestInstanceIdAfterMove,
751 _DestAttrNameAfterMove,
752 _DestPositionAfterMove,
753 _SrcInstanceIdInParent,
754 _SrcAttrNameInParent,
755 _SrcPositionInParent);
756 // send to network
757 dmc->doRequestMoveNode(_DestInstanceIdAfterMove,
758 _DestAttrNameAfterMove,
759 _DestPositionAfterMove,
760 _SrcInstanceIdInParent,
761 _SrcAttrNameInParent,
762 _SrcPositionInParent);
776 } // R2