forestUndo.cpp
Engine/source/forest/editor/forestUndo.cpp
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