persistenceManager.h
Engine/source/console/persistenceManager.h
Classes:
class
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#ifndef _PERSISTENCEMANAGER_H_ 25#define _PERSISTENCEMANAGER_H_ 26 27#ifndef _SIMOBJECT_H_ 28#include "console/simObject.h" 29#endif 30 31#ifndef _SIMOBJECTLIST_H_ 32#include "console/simObjectList.h" 33#endif 34 35#ifndef _TOKENIZER_H_ 36#include "core/tokenizer.h" 37#endif 38 39class PersistenceManager : public SimObject 40{ 41public: 42 struct ParsedProperty 43 { 44 StringTableEntry name; 45 const char* value; 46 47 U32 arrayPos; 48 49 S32 startLine; 50 S32 endLine; 51 52 S32 startPosition; 53 S32 endPosition; 54 55 S32 valueLine; 56 S32 valuePosition; 57 58 ParsedProperty() 59 { 60 name = NULL; 61 value = NULL; 62 63 arrayPos = 0; 64 65 startLine = -1; 66 endLine = -1; 67 68 startPosition = -1; 69 endPosition = -1; 70 71 valueLine = -1; 72 valuePosition = -1; 73 } 74 }; 75 76 struct ParsedObject 77 { 78 StringTableEntry name; 79 StringTableEntry className; 80 81 ParsedObject* parentObject; 82 83 SimObjectPtr<SimObject> simObject; 84 85 S32 nameLine; 86 S32 namePosition; 87 88 S32 startLine; 89 S32 endLine; 90 91 S32 startPosition; 92 S32 endPosition; 93 94 bool hasBraces; 95 96 bool updated; 97 98 Vector<ParsedProperty> properties; 99 100 ParsedObject() 101 { 102 name = NULL; 103 className = NULL; 104 105 parentObject = NULL; 106 107 simObject = NULL; 108 109 nameLine = -1; 110 namePosition = -1; 111 112 startLine = -1; 113 endLine = -1; 114 115 startPosition = -1; 116 endPosition = -1; 117 118 hasBraces = true; 119 120 updated = false; 121 } 122 }; 123 124 struct DirtyObject 125 { 126 SimObjectPtr<SimObject> *object; 127 StringTableEntry fileName; 128 129 bool isNull() const { return object->isNull(); } 130 131 void setObject( SimObject* newObject ) { *object = newObject; } 132 133 SimObject* getObject() const { return object->getPointer(); } 134 135 DirtyObject() 136 { 137 object = new SimObjectPtr<SimObject>(); 138 fileName = NULL; 139 } 140 141 ~DirtyObject() 142 { 143 SAFE_DELETE( object ); 144 } 145 }; 146 147 struct RemoveField 148 { 149 SimObjectPtr<SimObject> object; 150 StringTableEntry fieldName; 151 U32 arrayPos; 152 153 RemoveField() 154 { 155 object = NULL; 156 fieldName = NULL; 157 arrayPos = 0; 158 } 159 }; 160 161 typedef Vector<DirtyObject> DirtyList; 162 163protected: 164 typedef SimObject Parent; 165 166 // Used to walk through the file and read out 167 // the SimObject's and their properties 168 Tokenizer mParser; 169 170 // List of the objects that are flagged as dirty 171 DirtyList mDirtyObjects; 172 173 // List of fields to be removed from the objects declaration in the file 174 Vector<RemoveField> mRemoveFields; 175 176 // Temp buffers used during file parsing 177 ParsedObject* mCurrentObject; 178 Vector<ParsedObject*> mObjectStack; 179 180 // Buffers used on a per-file basis 181 Vector<const char*> mLineBuffer; 182 Vector<ParsedObject*> mObjectBuffer; 183 184 // Name of the currently open file 185 const char* mCurrentFile; 186 187 // Sort by filename 188 static S32 QSORT_CALLBACK compareFiles(const void* a, const void* b); 189 190 // Deletes and clears the line buffer 191 void clearLineBuffer(); 192 193 // Deletes the objects and its properties 194 void deleteObject(ParsedObject* object); 195 // Deletes and clears the object buffer, 196 // the object stack, and the current object 197 void clearObjects(); 198 199 // Clears all of the data related to the 200 // currently loaded file 201 void clearFileData(); 202 203 // Updates the changed values of a dirty object 204 // Also handles a new object 205 void updateObject(SimObject* object, ParsedObject* parentObject = NULL); 206 207 // Removes the current object without saving it 208 void killObject(); 209 // Saves the current object and restores the last object in the stack (if any) 210 void saveObject(); 211 // Parses an object from the current position in the parser 212 void parseObject(); 213 214 // Reads the file into the line buffer 215 bool readFile(const char* fileName); 216 // Parses the ParsedObjects out of the file 217 bool parseFile(const char* fileName); 218 219 // Writes the line buffer out to the current file 220 bool saveDirtyFile(); 221 222 // Attempts to look up the property in the ParsedObject 223 S32 getPropertyIndex(ParsedObject* parsedObject, const char* fieldName, U32 arrayPos = 0); 224 225 // Gets the amount of indent on the ParsedObject. 226 char* getObjectIndent(ParsedObject* object); 227 228 // Loops through all of the objects and properties that are on the same 229 // line after the startPos and updates their position offests accordingly 230 void updatePositions(U32 lineNumber, U32 startPos, S32 diff); 231 232 // Loops thought all of the objects and updates their line offsets 233 void updateLineOffsets(U32 startLine, S32 diff, ParsedObject* skipObject = NULL); 234 235 // Replaces a token on a given line with a new value 236 // This also calls updatePositions() to account for size 237 // differences between the old token and the new token 238 void updateToken(const U32 lineNumber, const U32 linePosition, const U32 oldValueLen, const char* newValue, bool addQuotes = false); 239 240 // Gets the field value from the SimObject. Note that this does 241 // allocate memory that needs to be cleaned up elsewhere 242 const char* getFieldValue(SimObject* object, const char* fieldName, U32 arrayPos); 243 244 // Attempt to find the parent object 245 ParsedObject* findParentObject(SimObject* object, ParsedObject* parentObject = NULL); 246 247 // Attempt to find the matching ParsedObject in our object buffer 248 ParsedObject* findParsedObject(SimObject* object, ParsedObject* parentObject = NULL); 249 250 // Attempt to find the matching DirtyObject for a passed SimObject in our DirtyItems list. 251 DirtyObject* findDirtyObject(SimObject* object); 252 253 // Is this field on the remove list 254 bool findRemoveField(SimObject* object, const char* fieldName, U32 arrayPos = 0); 255 256 // Helper function that allocates a new string and properly formats the data into it 257 // Note that this allocates memory that needs to be cleaned up elsewhere 258 const char* createNewProperty(const char* name, const char* value, bool isArray = false, U32 arrayPos = 0); 259 260 // Test to see if there is anything valid on the line 261 bool isEmptyLine(const char* line); 262 263 // Removes a line safely from the line buffer 264 void removeLine(U32 lineNumber); 265 // Remove a block of text from the line buffer. It returns 266 // the number of lines removed if removeEmptyLines is set to true. 267 void removeTextBlock(U32 startLine, U32 endLine, U32 startPos, U32 endPos, bool removeEmptyLines); 268 // Removes a ParsedObject from the line buffer 269 // (everything from the startLine to the endLine) 270 void removeParsedObject(ParsedObject* parsedObject); 271 // Removes a property from the line buffer 272 void removeField(const ParsedProperty& prop); 273 274 // Write out properties 275 // Returns the number of new lines added 276 U32 writeProperties(const Vector<const char*>& properties, const U32 insertLine, const char* objectIndent); 277 // Write out a new object 278 ParsedObject* writeNewObject(SimObject* object, const Vector<const char*>& properties, const U32 insertLine, ParsedObject* parentObject = NULL); 279 280public: 281 PersistenceManager(); 282 virtual ~PersistenceManager(); 283 284 bool onAdd(); 285 void onRemove(); 286 287 // Adds an object to the dirty list 288 // Optionally changes the object's filename 289 bool setDirty(SimObject* object, const char* fileName = NULL); 290 // Removes the object from the dirty list 291 void removeDirty(SimObject* object); 292 293 // Add a field to the remove list to cut it out of the object's declaration 294 void addRemoveField(SimObject* object, const char* fieldName); 295 296 // Test to see if an object is on the dirty list 297 bool isDirty(SimObject* object); 298 299 // Returns whether or not there are dirty objects 300 bool hasDirty() const { return !mDirtyObjects.empty(); } 301 302 // Saves the dirty objects out to their respective files 303 // and clears the dirty object data 304 bool saveDirty(); 305 306 // Saves out a single object, if it's dirty 307 bool saveDirtyObject(SimObject* object); 308 309 // Clears all of the dirty object data 310 void clearAll(); 311 312 // Removes the object from the file 313 void removeObjectFromFile(SimObject* object, const char* fileName = NULL); 314 315 // Deletes all of the objects that were created from this file 316 void deleteObjectsFromFile(const char* fileName); 317 318 // Returns a list of the dirty objects 319 const DirtyList& getDirtyList() { return mDirtyObjects; } 320 321 DECLARE_CONOBJECT(PersistenceManager); 322}; 323 324#endif 325