CUndoable.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // CUndoable.h
  19. // Class to handle undo/redo.
  20. // Author: John Ahlquist, April 2001
  21. #pragma once
  22. #ifndef CUNDOABLE_H
  23. #define CUNDOABLE_H
  24. #include "Lib\BaseType.h"
  25. #include "../../gameengine/include/common/MapObject.h"
  26. #include "../../gameengine/include/common/GameCommon.h"
  27. #include "../../gameengine/include/GameLogic/SidesList.h"
  28. #include "RefCount.h"
  29. #include <vector>
  30. class PolygonTrigger;
  31. class BuildListInfo;
  32. /*************************************************************************
  33. ** Undoable
  34. ***************************************************************************/
  35. /// Base command class for all undoable commands. Just the virtual shell.
  36. class Undoable : public RefCountClass
  37. {
  38. protected:
  39. Undoable *mNext;
  40. public:
  41. Undoable(void);
  42. ~Undoable(void);
  43. public:
  44. virtual void Do(void)=0; ///< pure virtual.
  45. virtual void Undo(void)=0;///< pure virtual.
  46. virtual void Redo(void);
  47. void LinkNext(Undoable *pNext);
  48. Undoable *GetNext(void) {return mNext;};
  49. };
  50. class CWorldBuilderDoc;
  51. class WorldHeightMapEdit;
  52. class MapObject;
  53. /*************************************************************************
  54. ** CWBDocUndoable
  55. ***************************************************************************/
  56. /// Command that saves & restores entire height map.
  57. /** An undoable that actually undoes something. Saves and restores the
  58. entire height map. */
  59. class WBDocUndoable : public Undoable
  60. {
  61. protected:
  62. CWorldBuilderDoc *mPDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  63. WorldHeightMapEdit *mPNewHeightMapData; ///< ref counted.
  64. WorldHeightMapEdit *mPOldHeightMapData; ///< ref counted.
  65. Bool m_offsetObjects; ///< If true, apply m_objOffset.
  66. Coord3D m_objOffset; ///< Offset to adjust all objects.
  67. public:
  68. WBDocUndoable(CWorldBuilderDoc *pDoc, WorldHeightMapEdit *pNewHtMap, Coord3D *pObjOffset = NULL);
  69. // destructor.
  70. ~WBDocUndoable(void);
  71. virtual void Do(void);
  72. virtual void Undo(void);
  73. virtual void Redo(void);
  74. };
  75. /// AddObjectUndoable
  76. /** An undoable that actually undoes something. Adds an object
  77. to the height map. If it is a linked list, adds all objects. */
  78. class AddObjectUndoable : public Undoable
  79. {
  80. protected:
  81. CWorldBuilderDoc *m_pDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  82. MapObject *m_objectToAdd;
  83. Int m_numObjects;
  84. Bool m_addedToList;
  85. public:
  86. AddObjectUndoable(CWorldBuilderDoc *pDoc, MapObject *pObjectToAdd);
  87. // destructor.
  88. ~AddObjectUndoable(void);
  89. virtual void Do(void);
  90. virtual void Undo(void);
  91. };
  92. /// ModifyObjectUndoable
  93. /** An undoable that actually undoes something. Modifies an object's
  94. location and angle. */
  95. // Helper class
  96. class MoveInfo
  97. {
  98. public:
  99. MoveInfo(MapObject *pObjToMove);
  100. ~MoveInfo();
  101. void DoMove(CWorldBuilderDoc *pDoc);
  102. void UndoMove(CWorldBuilderDoc *pDoc);
  103. void SetOffset(CWorldBuilderDoc *pDoc, Real x, Real y);
  104. void SetZOffset(CWorldBuilderDoc *pDoc, Real z);
  105. void RotateTo(CWorldBuilderDoc *pDoc, Real angle);
  106. void SetThingTemplate(CWorldBuilderDoc *pDoc, const ThingTemplate* thing);
  107. void SetName(CWorldBuilderDoc *pDoc, AsciiString name);
  108. public:
  109. MapObject *m_objectToModify;
  110. MoveInfo *m_next;
  111. Real m_newAngle;
  112. Real m_oldAngle;
  113. Coord3D m_newLocation;
  114. Coord3D m_oldLocation;
  115. const ThingTemplate* m_oldThing;
  116. const ThingTemplate* m_newThing;
  117. AsciiString m_oldName;
  118. AsciiString m_newName;
  119. };
  120. class ModifyObjectUndoable : public Undoable
  121. {
  122. protected:
  123. CWorldBuilderDoc* m_pDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  124. MoveInfo* m_moveList;
  125. Bool m_inval;
  126. public:
  127. ModifyObjectUndoable(CWorldBuilderDoc *pDoc);
  128. // destructor.
  129. ~ModifyObjectUndoable(void);
  130. virtual void Do(void);
  131. virtual void Undo(void);
  132. virtual void Redo(void);
  133. void SetOffset(Real x, Real y);
  134. void SetZOffset(Real z);
  135. void RotateTo(Real angle);
  136. void SetThingTemplate(const ThingTemplate* thing);
  137. void SetName(AsciiString name);
  138. };
  139. /// ModifyFlagsUndoable
  140. /** An undoable that actually undoes something. Modifies an object's
  141. flags. */
  142. // Helper class
  143. class FlagsInfo
  144. {
  145. public:
  146. FlagsInfo(MapObject *pObjToMove, Int flagMask, Int flagValue );
  147. ~FlagsInfo();
  148. void DoFlags(CWorldBuilderDoc *pDoc);
  149. void UndoFlags(CWorldBuilderDoc *pDoc);
  150. public:
  151. MapObject *m_objectToModify;
  152. FlagsInfo *m_next;
  153. Int m_flagMask;
  154. Int m_newValue;
  155. Int m_oldValue;
  156. };
  157. class ModifyFlagsUndoable : public Undoable
  158. {
  159. protected:
  160. CWorldBuilderDoc *m_pDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  161. FlagsInfo *m_flagsList;
  162. public:
  163. ModifyFlagsUndoable(CWorldBuilderDoc *pDoc, Int flagMask, Int flagValue);
  164. // destructor.
  165. ~ModifyFlagsUndoable(void);
  166. virtual void Do(void);
  167. virtual void Undo(void);
  168. virtual void Redo(void);
  169. };
  170. class SidesListUndoable : public Undoable
  171. {
  172. protected:
  173. SidesList m_old, m_new;
  174. CWorldBuilderDoc *m_pDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  175. public:
  176. SidesListUndoable(const SidesList& newSL, CWorldBuilderDoc *pDoc);
  177. ~SidesListUndoable(void);
  178. virtual void Do(void);
  179. virtual void Undo(void);
  180. };
  181. class DictItemUndoable : public Undoable
  182. {
  183. protected:
  184. Int m_numDictsToModify;
  185. std::vector<Dict*> m_dictToModify;
  186. std::vector<Dict> m_oldDictData;
  187. Dict m_newDictData;
  188. CWorldBuilderDoc *m_pDoc;
  189. Bool m_inval;
  190. NameKeyType m_key;
  191. public:
  192. static Dict buildSingleItemDict(AsciiString k, Dict::DataType t, AsciiString v);
  193. // if you want to just add/modify/remove a single dict item, pass the item's key.
  194. // if you want to substitute the entire contents of the new dict, pass NAMEKEY_INVALID.
  195. DictItemUndoable(Dict **d, Dict data, NameKeyType key, Int dictsToModify = 1, CWorldBuilderDoc *pDoc = NULL, Bool inval = false);
  196. // destructor.
  197. ~DictItemUndoable(void);
  198. virtual void Do(void);
  199. virtual void Undo(void);
  200. };
  201. /// DeleteObjectUndoable
  202. /** An undoable that actually undoes something. Deletes an object. */
  203. // Helper class
  204. class DeleteInfo
  205. {
  206. public:
  207. DeleteInfo(MapObject *pObjToDelete);
  208. ~DeleteInfo(void);
  209. void DoDelete(WorldHeightMapEdit *pMap);
  210. void UndoDelete(WorldHeightMapEdit *pMap);
  211. public:
  212. Bool m_didDelete;
  213. MapObject *m_objectToDelete;
  214. MapObject *m_priorObject;
  215. DeleteInfo *m_next;
  216. };
  217. class DeleteObjectUndoable : public Undoable
  218. {
  219. protected:
  220. CWorldBuilderDoc *m_pDoc; ///< Not ref counted. This undoable should be in a list attached to the doc anyway.
  221. DeleteInfo *m_deleteList;
  222. public:
  223. DeleteObjectUndoable(CWorldBuilderDoc *pDoc);
  224. // destructor.
  225. ~DeleteObjectUndoable(void);
  226. virtual void Do(void);
  227. virtual void Undo(void);
  228. };
  229. /// AddPolygonUndoable
  230. /** An undoable that actually undoes something. Adds a polygon. */
  231. class AddPolygonUndoable : public Undoable
  232. {
  233. protected:
  234. PolygonTrigger *m_trigger;
  235. Bool m_isTriggerInList;
  236. public:
  237. AddPolygonUndoable( PolygonTrigger *pTrig);
  238. // destructor.
  239. ~AddPolygonUndoable(void);
  240. virtual void Do(void);
  241. virtual void Undo(void);
  242. };
  243. /// AddPolygonPointUndoable
  244. /** An undoable that actually undoes something. Adds a polygon. */
  245. class AddPolygonPointUndoable : public Undoable
  246. {
  247. protected:
  248. PolygonTrigger *m_trigger;
  249. ICoord3D m_point;
  250. public:
  251. AddPolygonPointUndoable(PolygonTrigger *pTrig, ICoord3D pt);
  252. // destructor.
  253. ~AddPolygonPointUndoable(void);
  254. virtual void Do(void);
  255. virtual void Undo(void);
  256. };
  257. /// ModifyPolygonPointUndoable
  258. /** An undoable that actually undoes something. Modifys a polygon. */
  259. class ModifyPolygonPointUndoable : public Undoable
  260. {
  261. protected:
  262. PolygonTrigger *m_trigger;
  263. Int m_pointIndex;
  264. ICoord3D m_point;
  265. ICoord3D m_savPoint;
  266. public:
  267. ModifyPolygonPointUndoable(PolygonTrigger *pTrig, Int ndx);
  268. // destructor.
  269. ~ModifyPolygonPointUndoable(void);
  270. virtual void Do(void);
  271. virtual void Undo(void);
  272. };
  273. /// MovePolygonUndoable
  274. /** An undoable that actually undoes something. Moves a polygon. */
  275. class MovePolygonUndoable : public Undoable
  276. {
  277. protected:
  278. PolygonTrigger *m_trigger;
  279. ICoord3D m_point;
  280. ICoord3D m_offset;
  281. public:
  282. MovePolygonUndoable(PolygonTrigger *pTrig);
  283. // destructor.
  284. ~MovePolygonUndoable(void);
  285. virtual void Do(void);
  286. virtual void Undo(void);
  287. void SetOffset(const ICoord3D &offset);
  288. PolygonTrigger *getTrigger(void) {return m_trigger;}
  289. };
  290. /// InsertPolygonPointUndoable
  291. /** An undoable that actually undoes something. Inserts a polygon point. */
  292. class InsertPolygonPointUndoable : public Undoable
  293. {
  294. protected:
  295. PolygonTrigger *m_trigger;
  296. Int m_pointIndex;
  297. ICoord3D m_point;
  298. public:
  299. InsertPolygonPointUndoable(PolygonTrigger *pTrig, ICoord3D pt, Int ndx);
  300. // destructor.
  301. ~InsertPolygonPointUndoable(void);
  302. virtual void Do(void);
  303. virtual void Undo(void);
  304. };
  305. /// DeletePolygonPointUndoable
  306. /** An undoable that actually undoes something. Deletes a polygon point. */
  307. class DeletePolygonPointUndoable : public Undoable
  308. {
  309. protected:
  310. PolygonTrigger *m_trigger;
  311. Int m_pointIndex;
  312. ICoord3D m_point;
  313. public:
  314. DeletePolygonPointUndoable(PolygonTrigger *pTrig, Int ndx);
  315. // destructor.
  316. ~DeletePolygonPointUndoable(void);
  317. virtual void Do(void);
  318. virtual void Undo(void);
  319. };
  320. /// DeletePolygonUndoable
  321. /** An undoable that actually undoes something. Deletes a polygon. */
  322. class DeletePolygonUndoable : public Undoable
  323. {
  324. protected:
  325. PolygonTrigger *m_trigger;
  326. Bool m_isTriggerInList;
  327. public:
  328. DeletePolygonUndoable(PolygonTrigger *pTrig);
  329. // destructor.
  330. ~DeletePolygonUndoable(void);
  331. virtual void Do(void);
  332. virtual void Undo(void);
  333. };
  334. /// MultipleUndoable
  335. /**
  336. * An undoable that doesn't do anything; it just consolidates a number of other
  337. * Undoables in a single logical undo step.
  338. */
  339. class MultipleUndoable : public Undoable
  340. {
  341. protected:
  342. Undoable * m_undoableList; //< The head of the list of undoables, in the order they should be done. Reverse order for undoes
  343. public:
  344. MultipleUndoable();
  345. // destructor.
  346. ~MultipleUndoable(void);
  347. /** Add other undoables in the order you would want them UNdone; e.g. in the reverse order you want them done
  348. * The MultipleUndoable object will then own the pointers.
  349. */
  350. void addUndoable( Undoable * undoable );
  351. virtual void Do(void);
  352. virtual void Undo(void);
  353. virtual void Redo(void);
  354. };
  355. #endif //CUNDOABLE_H