forestUndo.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "forest/editor/forestUndo.h"
  24. #include "forest/forestDataFile.h"
  25. #include "forest/editor/forestEditorCtrl.h"
  26. ForestUndoAction::ForestUndoAction( const Resource<ForestData> &data,
  27. ForestEditorCtrl *editor,
  28. const char *description )
  29. : UndoAction( description ),
  30. mEditor( editor ),
  31. mData( data )
  32. {
  33. }
  34. ForestCreateUndoAction::ForestCreateUndoAction( const Resource<ForestData> &data,
  35. ForestEditorCtrl *editor )
  36. : ForestUndoAction( data, editor, "Create Forest Items" )
  37. {
  38. }
  39. void ForestCreateUndoAction::addItem( ForestItemData *data,
  40. const Point3F &position,
  41. F32 rotation,
  42. F32 scale )
  43. {
  44. const ForestItem &item = mData->addItem( data, position, rotation, scale );
  45. mItems.push_back( item );
  46. // We store the datablock ID rather than the actual pointer
  47. // since the pointer could go bad.
  48. SimObjectId dataId = item.getData()->getId();
  49. mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
  50. }
  51. void ForestCreateUndoAction::redo()
  52. {
  53. for ( U32 i = 0; i < mItems.size(); i++ )
  54. {
  55. const ForestItem &item = mItems[i];
  56. // Not 64bit safe!
  57. // We store the datablock ID rather than the actual pointer
  58. // since the pointer could go bad.
  59. ForestItemData *data;
  60. if ( !Sim::findObject( (SimObjectId)(uintptr_t)(item.getData()), data ) )
  61. {
  62. Con::errorf( "ForestCreateUndoAction::redo() - ForestItemData for item to restore does not seem to exist. Undo stack may be hosed." );
  63. continue;
  64. }
  65. mData->addItem( item.getKey(),
  66. data,
  67. item.getTransform(),
  68. item.getScale() );
  69. }
  70. mEditor->onUndoAction();
  71. }
  72. void ForestCreateUndoAction::undo()
  73. {
  74. for ( S32 i = mItems.size()-1; i >= 0; i-- )
  75. {
  76. const ForestItem &item = mItems[i];
  77. mData->removeItem( item.getKey(), item.getPosition() );
  78. }
  79. mEditor->onUndoAction();
  80. }
  81. ForestDeleteUndoAction::ForestDeleteUndoAction( const Resource<ForestData> &data,
  82. ForestEditorCtrl *editor )
  83. : ForestUndoAction( data, editor, "Delete Forest Items" )
  84. {
  85. }
  86. void ForestDeleteUndoAction::removeItem( const ForestItem &item )
  87. {
  88. // Not 64bit safe!
  89. // We store the datablock ID rather than the actual pointer
  90. // since the pointer could go bad.
  91. SimObjectId dataId = item.getData()->getId();
  92. mItems.push_back( item );
  93. mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
  94. mData->removeItem( item.getKey(), item.getPosition() );
  95. }
  96. void ForestDeleteUndoAction::removeItem( const Vector<ForestItem> &itemList )
  97. {
  98. for ( S32 i = 0; i < itemList.size(); i++ )
  99. removeItem( itemList[i] );
  100. }
  101. void ForestDeleteUndoAction::redo()
  102. {
  103. for ( U32 i = 0; i < mItems.size(); i++ )
  104. {
  105. const ForestItem &item = mItems[i];
  106. mData->removeItem( item.getKey(), item.getPosition() );
  107. }
  108. mEditor->onUndoAction();
  109. }
  110. void ForestDeleteUndoAction::undo()
  111. {
  112. for ( S32 i = mItems.size()-1; i >= 0; i-- )
  113. {
  114. const ForestItem &item = mItems[i];
  115. // We store the datablock ID rather than the actual pointer
  116. // since the pointer could go bad.
  117. ForestItemData *data;
  118. if ( !Sim::findObject( (SimObjectId)(uintptr_t)(item.getData()), data ) )
  119. {
  120. Con::errorf( "ForestDeleteUndoAction::undo() - ForestItemData for item to restore does not seem to exist. Undo stack may be hosed." );
  121. continue;
  122. }
  123. mData->addItem( item.getKey(),
  124. data,
  125. item.getTransform(),
  126. item.getScale() );
  127. }
  128. mEditor->onUndoAction();
  129. }
  130. ForestUpdateAction::ForestUpdateAction( const Resource<ForestData> &data,
  131. ForestEditorCtrl *editor )
  132. : ForestUndoAction( data, editor, "Update Forest Items" )
  133. {
  134. }
  135. void ForestUpdateAction::saveItem( const ForestItem &item )
  136. {
  137. // We just store the current state... we undo it later.
  138. mItems.push_back( item );
  139. // We store the datablock ID rather than the actual pointer
  140. // since the pointer could go bad.
  141. SimObjectId dataId = item.getData()->getId();
  142. mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
  143. }
  144. void ForestUpdateAction::_swapState()
  145. {
  146. Vector<ForestItem> prevItems = mItems;
  147. mItems.clear();
  148. for ( U32 i=0; i < prevItems.size(); i++ )
  149. {
  150. const ForestItem &item = prevItems[i];
  151. // Save the current state so we can reverse this swap.
  152. //
  153. // Note that we do 'not' want the const ref returned by findItem
  154. // because when we call updateItem below we would lose our copy
  155. // of the items state before the call.
  156. //
  157. ForestItem newItem = mData->findItem( item.getKey() );
  158. if ( !newItem.isValid() )
  159. {
  160. Con::errorf( "ForestUpdateAction::_swapState() - saved item no longer exists. Undo stack may be hosed." );
  161. continue;
  162. }
  163. // Not 64bit safe!
  164. // We store the datablock ID rather than the actual pointer
  165. // since the pointer could go bad.
  166. ForestItemData *data;
  167. if ( !Sim::findObject( (SimObjectId)(uintptr_t)(item.getData()), data ) )
  168. {
  169. Con::errorf( "ForestUpdateAction::_swapState() - ForestItemData for item to restore does not seem to exist. Undo stack may be hosed." );
  170. continue;
  171. }
  172. // Now revert to the old state.
  173. mData->updateItem( item.getKey(),
  174. item.getPosition(),
  175. data,
  176. item.getTransform(),
  177. item.getScale() );
  178. // Save the state before this swap for the next swap.
  179. newItem.setData( (ForestItemData*)(uintptr_t)data->getId() );
  180. mItems.push_back( newItem );
  181. }
  182. mEditor->onUndoAction();
  183. }