Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / client / src / r2 / dmc / action_historic.h
blobfef3a9971388b765b2ae8c447b0dc5e8dfa6581e
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef R2_ACTION_HISTORIC_H
18 #define R2_ACTION_HISTORIC_H
20 #include "nel/misc/historic.h"
21 #include "nel/misc/smart_ptr.h"
22 #include "nel/misc/ucstring.h"
24 #include "game_share/object.h"
25 #include "game_share/scenario.h"
27 namespace R2
30 class IDynamicMapClient;
32 // An undo / redo historic
33 class CActionHistoric
35 public:
36 CActionHistoric();
37 ~CActionHistoric();
38 void setDMC(IDynamicMapClient *dmc) { _DMC = dmc; }
39 /** Signal the beginning of a new action. Calling this twice in a row will not create
40 * an empty action.
42 void newSingleAction(const ucstring &name);
43 /** Begin a new action composed of several subactions. 'numSubActions' calls to 'newAction' will be expected
44 * before the merge of the subactions is pushed
46 void newMultiAction(const ucstring &name, uint actionCount);
47 /** Begin a new action composed of several subactions. 'numSubActions' calls to 'newAction' will be expected
48 * before the merge of the subactions is pushed
50 void newPendingMultiAction(const ucstring &name, uint actionCount);
51 /** Begin a new 'pending' action
52 * Unlike 'newAction', requests of the actions are sent at each call
53 * to the 'request' commands, not when the action is finished.
54 * Use this if you can't issue an action in a single row (may happen
55 * if some requests in the action depends on notifications sent by previous requests)
57 void newPendingAction(const ucstring &name);
59 // force to end a multi action, event if the action count hasnt been reached
60 void forceEndMultiAction();
62 // End last action / pending action
63 void endAction();
64 // cancel any action, including multi action
65 void cancelAction();
66 // If there's a pending action for this frame, flush its content
67 void flushPendingAction();
68 // Test if a pending action has been begun
69 bool isPendingActionInProgress() const { return _NewActionIsPending; }
70 // get number of completed actions (do not include the new action being built)
71 uint getNumActions() const { return _Actions.getSize(); }
72 bool isNewActionBeingRecorded() const { return _NewAction != NULL; }
73 uint getMaxNumActions() const { return _Actions.getMaxSize(); }
74 void setMaxNumActions(uint count);
75 // clear
76 void clear(CObject *newScenario = NULL);
77 // get name of next action that can be redone
78 const ucstring *getNextActionName() const;
79 // get name of previous action that can be undone
80 const ucstring *getPreviousActionName() const;
81 // Test if an action can be undone
82 bool canUndo() const;
83 // Test if an action can be redo
84 bool canRedo() const;
85 // undo last action, if possible (return true on success)
86 bool undo();
87 // redo last action, if possible (return true on success)
88 bool redo();
89 // push requests into current action
90 void requestInsertNode(const std::string& instanceId, const std::string& name, sint32 position, const std::string& key, CObject* value);
91 void requestSetNode(const std::string& instanceId, const std::string& attrName, CObject* value);
92 void requestEraseNode(const std::string& instanceId, const std::string& attrName, sint32 position);
93 void requestMoveNode(const std::string& instanceId, const std::string& attrName, sint32 position, const std::string& destInstanceId, const std::string& destAttrName, sint32 destPosition);
94 //Uundo supported only if 'clear' was called with a scenario pointer
95 //Only 'redo' supported else
96 bool isUndoSupported() const { return _Scenario.getHighLevel() != NULL; }
97 private:
98 // base for all requests
99 class CRequestBase : public NLMISC::CRefCount
101 public:
102 typedef NLMISC::CSmartPtr<CRequestBase> TSmartPtr;
103 virtual ~CRequestBase() {}
104 virtual void redo(IDynamicMapClient *dmc, CScenario &scenario) = 0;
105 virtual void undo(IDynamicMapClient *dmc, CScenario &scenario) = 0;
106 protected:
107 // clone an object, and disable its refids objects (these object would send
108 // creation notifications otherwise)
109 public:
110 static CObject *cloneObject(const CObject *src);
112 /** An atomic list of requests.
113 * Once redo / undo have been called, no other requests can be pushed into this action,
114 * so calls to 'pushRequest' will assert.
116 class CAction : public NLMISC::CRefCount
118 public:
119 typedef NLMISC::CSmartPtr<CAction> TSmartPtr;
120 CAction(const ucstring &name);
121 ~CAction();
122 void setCompleted() { _Completed = true; }
123 void pushRequest(CRequestBase *req);
124 // For pending action : flush the content that has already been pushed using 'pushRequest'
125 // This should be called before 'setCompleted'
126 void flush(IDynamicMapClient *dmc, CScenario &scenario);
127 // If content has been flushed, rollback the modifications
128 void rollback(IDynamicMapClient *dmc, CScenario &scenario);
130 void redo(IDynamicMapClient *dmc, CScenario &scenario);
131 void undo(IDynamicMapClient *dmc, CScenario &scenario);
132 const ucstring &getName() const { return _Name; }
133 private:
134 ucstring _Name;
135 std::vector<CRequestBase::TSmartPtr> _Requests;
136 uint _FlushedCount;
137 bool _Completed;
138 bool _Flushing;
140 //////////////
141 // REQUESTS //
142 //////////////
143 class CRequestSetNode : public CRequestBase
145 public:
146 CRequestSetNode(const std::string& instanceId, const std::string& attrName, CObject* value);
147 // from CRequestBase
148 virtual void redo(IDynamicMapClient *dmc, CScenario &scenario);
149 virtual void undo(IDynamicMapClient *dmc, CScenario &scenario);
150 private:
151 std::string _InstanceId;
152 std::string _AttrName;
153 CObject::TSmartPtr _NewValue;
154 CObject::TSmartPtr _OldValue;
157 class CRequestEraseNode : public CRequestBase
159 public:
160 CRequestEraseNode(const std::string& instanceId, const std::string& attrName, sint32 position);
161 // from CRequestBase
162 virtual void redo(IDynamicMapClient *dmc, CScenario &scenario);
163 virtual void undo(IDynamicMapClient *dmc, CScenario &scenario);
164 private:
165 // point of deletion
166 std::string _InstanceId;
167 std::string _AttrName;
168 sint32 _Position;
169 CObject::TSmartPtr _OldValue;
170 // name in parent
171 std::string _ParentInstanceId;
172 std::string _AttrNameInParent;
173 sint32 _PositionInParent;
176 class CRequestInsertNode : public CRequestBase
178 public:
179 CRequestInsertNode(const std::string& instanceId, const std::string& attrName, sint32 position, const std::string& key, CObject* value);
180 // from CRequestBase
181 virtual void redo(IDynamicMapClient *dmc, CScenario &scenario);
182 virtual void undo(IDynamicMapClient *dmc, CScenario &scenario);
183 private:
184 std::string _InstanceId;
185 std::string _AttrName;
186 sint32 _Position;
187 std::string _Key;
188 CObject::TSmartPtr _Value;
191 class CRequestMoveNode : public CRequestBase
193 public:
194 CRequestMoveNode(const std::string& srcInstanceId,
195 const std::string& srcAttrName,
196 sint32 srcPosition,
197 const std::string& destInstanceId,
198 const std::string& destAttrName,
199 sint32 destPosition);
200 // from CRequestBase
201 virtual void redo(IDynamicMapClient *dmc, CScenario &scenario);
202 virtual void undo(IDynamicMapClient *dmc, CScenario &scenario);
203 private:
204 std::string _SrcInstanceId;
205 std::string _SrcAttrName;
206 sint32 _SrcPosition;
207 // name of source in parent for reciprocal move
208 std::string _SrcInstanceIdInParent;
209 std::string _SrcAttrNameInParent;
210 sint32 _SrcPositionInParent;
212 std::string _DestInstanceId;
213 std::string _DestAttrName;
214 sint32 _DestPosition;
215 // name of dest
216 std::string _DestInstanceIdAfterMove;
217 std::string _DestAttrNameAfterMove;
218 sint32 _DestPositionAfterMove;
220 private:
221 IDynamicMapClient *_DMC;
222 NLMISC::CHistoric<CAction::TSmartPtr> _Actions;
223 /** Index of current action relative to the end of the stack (-1 for the last action)
224 * Undo applies to this action, redo applies to the next action
226 sint _CurrActionIndex;
227 CAction::TSmartPtr _NewAction;
228 ucstring _NewActionName;
229 uint _SubActionCount;
230 bool _NewActionIsPending;
231 // anticipated scenario state,
232 CScenario _Scenario;
234 private:
235 // return previous action absolute index, or -1 if there's no previous action that can be undone.
236 sint getPreviousActionIndex() const;
237 // return next action absolute index, or -1 if there's no next action that can be undone.
238 sint getNextActionIndex() const;
241 } // R2
243 #endif