worldfile.hh
Go to the documentation of this file.
00001 /* 00002 * Stage : a multi-robot simulator. 00003 * Copyright (C) 2001, 2002 Richard Vaughan, Andrew Howard and Brian Gerkey. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 * 00019 */ 00020 /* 00021 * Desc: A class for reading in the world file. 00022 * Author: Andrew Howard, Richard Vaughan 00023 * Date: 15 Nov 2001 00024 * CVS info: $Id$ 00025 */ 00026 00027 #ifndef WORLDFILE_HH 00028 #define WORLDFILE_HH 00029 00030 00031 #include <stdint.h> // for portable int types eg. uint32_t 00032 #include <stdio.h> // for FILE ops 00033 00034 namespace Stg { 00035 00037 class CProperty 00038 { 00039 public: 00041 int entity; 00042 00044 std::string name; 00045 00047 std::vector<int> values; 00048 00050 int line; 00051 00053 bool used; 00054 00055 CProperty( int entity, const char* name, int line ) : 00056 entity(entity), 00057 name(name), 00058 values(), 00059 line(line), 00060 used(false) {} 00061 }; 00062 00063 00064 // Class for loading/saving world file. This class hides the syntax 00065 // of the world file and provides an 'entity.property = value' style 00066 // interface. Global settings go in entity 0; every other entity 00067 // refers to a specific entity. Parent/child relationships are 00068 // encoded in the form of entity/subentity relationships. 00069 class Worldfile 00070 { 00071 // Standard constructors/destructors 00072 public: Worldfile(); 00073 public: ~Worldfile(); 00074 00075 // replacement for fopen() that checks STAGEPATH dirs for the named file 00076 // (thanks to Douglas S. Blank <dblank@brynmawr.edu>) 00077 protected: FILE* FileOpen(const std::string& filename, const char* method); 00078 00079 // Load world from file 00080 public: bool Load(const std::string& filename ); 00081 00082 // Save world into named file 00083 public: bool Save(const std::string& filename); 00084 00085 // Check for unused properties and print warnings 00086 public: bool WarnUnused(); 00087 00088 // Read a string 00089 public: const std::string ReadString(int entity, const char* name, const std::string& value); 00090 00091 // Write a string 00092 public: void WriteString(int entity, const char *name, const std::string& value ); 00093 00094 // Read an integer 00095 public: int ReadInt(int entity, const char *name, int value); 00096 00097 // Write an integer 00098 public: void WriteInt(int entity, const char *name, int value); 00099 00100 // Read a float 00101 public: double ReadFloat(int entity, const char *name, double value); 00102 00103 // Write a float 00104 public: void WriteFloat(int entity, const char *name, double value); 00105 00106 // Read a length (includes unit conversion) 00107 public: double ReadLength(int entity, const char *name, double value) 00108 { 00109 return (ReadFloat( entity, name, value/unit_length ) * unit_length); 00110 } 00111 00112 // Write a length (includes units conversion) 00113 public: void WriteLength(int entity, const char *name, double value); 00114 00115 // Read an angle (includes unit conversion) 00116 public: double ReadAngle(int entity, const char *name, double value) 00117 { 00118 return (ReadFloat( entity, name, value/unit_angle ) * unit_angle); 00119 } 00120 00121 // Read a boolean 00122 // REMOVE? public: bool ReadBool(int entity, const char *name, bool value); 00123 00124 // Read a color (includes text to RGB conversion) 00125 public: uint32_t ReadColor(int entity, const char *name, uint32_t value); 00126 00127 // Read a file name. Always returns an absolute path. If the 00128 // filename is entered as a relative path, we prepend the world 00129 // files path to it. 00130 public: const char *ReadFilename(int entity, const char *name, const char *value); 00131 00132 // Read a series of values from a tuplee 00133 public: int ReadTuple( const int entity, const char* name, 00134 const unsigned int first, const unsigned int num, const char* format, ... ); 00135 00136 // Write a series of values to a tuple 00137 public: void WriteTuple( const int entity, const char *name, 00138 const unsigned int first, const unsigned int count, const char* format, ... ); 00139 00140 00142 // Private methods used to load stuff from the world file 00143 00144 // Load tokens from a file. 00145 private: bool LoadTokens(FILE *file, int include); 00146 00147 // Read in a comment token 00148 private: bool LoadTokenComment(FILE *file, int *line, int include); 00149 00150 // Read in a word token 00151 private: bool LoadTokenWord(FILE *file, int *line, int include); 00152 00153 // Load an include token; this will load the include file. 00154 private: bool LoadTokenInclude(FILE *file, int *line, int include); 00155 00156 // Read in a number token 00157 private: bool LoadTokenNum(FILE *file, int *line, int include); 00158 00159 // Read in a string token 00160 private: bool LoadTokenString(FILE *file, int *line, int include); 00161 00162 // Read in a whitespace token 00163 private: bool LoadTokenSpace(FILE *file, int *line, int include); 00164 00165 // Save tokens to a file. 00166 private: bool SaveTokens(FILE *file); 00167 00168 // Clear the token list 00169 private: void ClearTokens(); 00170 00171 // Add a token to the token list 00172 private: bool AddToken(int type, const char *value, int include); 00173 00174 // Set a token in the token list 00175 private: bool SetTokenValue(int index, const char *value); 00176 00177 // Get the value of a token 00178 private: const char *GetTokenValue(int index); 00179 00180 // Dump the token list (for debugging). 00181 private: void DumpTokens(); 00182 00183 // Parse a line 00184 private: bool ParseTokens(); 00185 00186 // Parse an include statement 00187 private: bool ParseTokenInclude(int *index, int *line); 00188 00189 // Parse a macro definition 00190 private: bool ParseTokenDefine(int *index, int *line); 00191 00192 // Parse an word (could be a entity or an property) from the token list. 00193 private: bool ParseTokenWord(int entity, int *index, int *line); 00194 00195 // Parse a entity from the token list. 00196 private: bool ParseTokenEntity(int entity, int *index, int *line); 00197 00198 // Parse an property from the token list. 00199 private: bool ParseTokenProperty(int entity, int *index, int *line); 00200 00201 // Parse a tuple. 00202 private: bool ParseTokenTuple( CProperty* property, int *index, int *line); 00203 00204 // Clear the macro list 00205 private: void ClearMacros(); 00206 00207 // Add a macro 00208 private: void AddMacro(const char *macroname, const char *entityname, 00209 int line, int starttoken, int endtoken); 00210 00211 // Lookup a macro by name 00212 00213 // Returns a pointer to a macro with this name, or NULL if there is none.. 00214 class CMacro; 00215 private: CMacro* LookupMacro(const char *macroname); 00216 00217 // Dump the macro list for debugging 00218 private: void DumpMacros(); 00219 00220 // Clear the entity list 00221 private: void ClearEntities(); 00222 00223 // Add a entity 00224 private: int AddEntity(int parent, const char *type); 00225 00226 // Get the number of entities. 00227 public: int GetEntityCount(); 00228 00229 // Get a entity (returns the entity type value) 00230 public: const char *GetEntityType(int entity); 00231 00232 // Lookup a entity number by type name 00233 // Returns -1 if there is entity with this type 00234 public: int LookupEntity(const char *type); 00235 00236 // Get a entity's parent entity. 00237 // Returns -1 if there is no parent. 00238 public: int GetEntityParent(int entity); 00239 00240 // Dump the entity list for debugging 00241 private: void DumpEntities(); 00242 00243 // Clear the property list 00244 private: void ClearProperties(); 00245 00246 // Add an property 00247 private: CProperty* AddProperty(int entity, const char *name, int line); 00248 // Add an property value. 00249 private: void AddPropertyValue( CProperty* property, int index, int value_token); 00250 00251 // Get an property 00252 public: CProperty* GetProperty(int entity, const char *name); 00253 00254 // returns true iff the property exists in the file, so that you can 00255 // be sure that GetProperty() will work 00256 bool PropertyExists( int section, const char* token ); 00257 00258 // Set the value of an property. 00259 private: void SetPropertyValue( CProperty* property, int index, const char *value); 00260 00261 // Get the value of an property. 00262 public: const char *GetPropertyValue( CProperty* property, int index); 00263 00264 // Dump the property list for debugging 00265 private: void DumpProperties(); 00266 00267 // Token types. 00268 private: enum 00269 { 00270 TokenComment, 00271 TokenWord, TokenNum, TokenString, 00272 TokenOpenEntity, TokenCloseEntity, 00273 TokenOpenTuple, TokenCloseTuple, 00274 TokenSpace, TokenEOL 00275 }; 00276 00277 // Token structure. 00278 private: 00279 class CToken 00280 { 00281 public: 00282 // Non-zero if token is from an include file. 00283 int include; 00284 00285 // Token type (enumerated value). 00286 int type; 00287 00288 // Token value 00289 std::string value; 00290 00291 CToken( int include, int type, const char* value ) : 00292 include(include), type(type), value(value) {} 00293 }; 00294 00295 // A list of tokens loaded from the file. 00296 // Modified values are written back into the token list. 00297 //private: int token_size, token_count; 00298 private: std::vector<CToken> tokens; 00299 00300 // Private macro class 00301 private: 00302 class CMacro 00303 { 00304 public: 00305 // Name of macro 00306 std::string macroname; 00307 00308 // Name of entity 00309 std::string entityname; 00310 00311 // Line the macro definition starts on. 00312 int line; 00313 00314 // Range of tokens in the body of the macro definition. 00315 int starttoken, endtoken; 00316 00317 CMacro(const char *macroname, const char *entityname, 00318 int line, int starttoken, int endtoken) : 00319 macroname(macroname), 00320 entityname(entityname), 00321 line(line), 00322 starttoken(starttoken), 00323 endtoken(endtoken) {} 00324 }; 00325 00326 // Macro table 00327 private: std::map<std::string,CMacro> macros; 00328 00329 // Private entity class 00330 private: 00331 class CEntity 00332 { 00333 public: 00334 // Parent entity 00335 int parent; 00336 00337 // Type of entity (i.e. position, laser, etc). 00338 std::string type; 00339 00340 CEntity( int parent, const char* type ) : parent(parent), type(type) {} 00341 }; 00342 00343 // Entity list 00344 private: std::vector<CEntity> entities; 00345 00346 // Property list 00347 private: std::map<std::string,CProperty*> properties; 00348 00349 // Name of the file we loaded 00350 public: std::string filename; 00351 00352 // Conversion units 00353 public: double unit_length; 00354 public: double unit_angle; 00355 00356 }; 00357 00358 }; 00359 00360 #endif