forestUndo.cpp

Engine/source/forest/editor/forestUndo.cpp

More...

Detailed Description

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