00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * guettler@informatik.uni-leipzig.de * 00007 * * 00008 * This program is free software; you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation; either version 2 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program; if not, write to the * 00020 * Free Software Foundation, Inc., * 00021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00022 *************************************************************************** 00023 * * 00024 * DESCRIPTION * 00025 * * 00026 * $Log: configurable.h,v $ 00027 * Revision 1.4 2008/08/14 08:06:02 robot1 00028 * fixed compile bug 00029 * 00030 * Revision 1.3 2008/08/01 14:42:03 guettler 00031 * we try the trip to hell! make selforg AVR compatible...good luck (first changes) 00032 * 00033 * Revision 1.2 2008/04/29 07:41:40 guettler 00034 * added GPL and revision tag 00035 * 00036 * Revision 1.1 2008/04/29 07:39:54 guettler 00037 * interfaces moved to selforg/utils directory 00038 * 00039 * Revision 1.7 2008/04/11 14:12:30 martius 00040 * comments paramter in storeCfg 00041 * 00042 * Revision 1.6 2007/06/08 15:44:32 martius 00043 * termination string -> more robust parsing 00044 * 00045 * Revision 1.5 2007/03/26 13:13:47 martius 00046 * store and restore with params 00047 * 00048 * Revision 1.4 2007/01/24 14:38:35 martius 00049 * new implementation with a map from key to reference. 00050 * addParameter and addParameterDef are used for registration of a parameter 00051 * the old style is still supported 00052 * 00053 * Revision 1.3 2006/07/14 12:23:57 martius 00054 * selforg becomes HEAD 00055 * 00056 * Revision 1.1.2.7 2006/06/25 21:56:07 martius 00057 * configureable has name and revision 00058 * 00059 * Revision 1.1.2.6 2006/02/08 16:17:40 martius 00060 * no namespace using 00061 * 00062 * Revision 1.1.2.5 2006/01/18 16:48:10 martius 00063 * configurables can be stored and reloaded 00064 * 00065 * Revision 1.1.2.4 2006/01/18 10:45:32 martius 00066 * *** empty log message *** 00067 * 00068 * Revision 1.1.2.3 2006/01/18 10:44:49 martius 00069 * (re)storeCfg 00070 * 00071 * Revision 1.1.2.2 2006/01/16 17:40:13 martius 00072 * parsing works 00073 * 00074 * Revision 1.1.2.1 2006/01/16 17:27:17 martius 00075 * *** empty log message *** 00076 * 00077 * * 00078 ***************************************************************************/ 00079 #ifndef __CONFIGURABLE_H 00080 #define __CONFIGURABLE_H 00081 00082 #ifndef AVR 00083 00084 // pc code below (x86 / x_64) 00085 00086 #include <iostream> 00087 00088 00089 #include <list> 00090 #include <utility> 00091 #include <string> 00092 #include <map> 00093 #include "stl_adds.h" 00094 00095 00096 /** 00097 Abstact class for configurable objects. Sort of Hashmap interface. Parameters are double values 00098 00099 The Configurator is a (planned) external tool that can be used for changing the values of configurable objects. 00100 00101 * Protocoll for Configurator: 00102 \code 00103 To Configurator (BNF notation): 00104 Conf := <Comp>* 00105 Comp := <CompName> <Pair>* 00106 CompName := [<string>][<int>]<newline> 00107 Pair := <alphanum>=<double><newline> 00108 \endcode 00109 the remaining tags are self explanatory 00110 00111 Example 00112 \code 00113 [Component name which can contain spaces and digits and .,- ][ID1] 00114 key1 = value1 00115 key2 = value2 00116 . 00117 . 00118 [Other Component name which can contain spaces and digits and .,- ][ID2] 00119 key3 = value3 00120 \endcode 00121 00122 Answer: (from Communicator to Simulation environment)\n 00123 1. On change of a parameter: 00124 \code 00125 [ID] key=newvalue 00126 \endcode 00127 or 00128 \code 00129 key=newvalue 00130 \endcode 00131 the latter one means that the parameter is changed in all components 00132 00133 2. Request of the description as defined above. 00134 \code 00135 #Something I don\'t care 00136 \endcode 00137 */ 00138 00139 class Configurable { 00140 public: 00141 00142 typedef std::string paramkey; 00143 typedef double paramval; 00144 typedef std::list< std::pair<paramkey, paramval> > paramlist; 00145 typedef std::map< paramkey, paramval* > parammap; 00146 00147 /// nice predicate function for finding by ID 00148 struct matchId : public std::unary_function<Configurable*, bool> { 00149 matchId(int id) : id(id) {} 00150 int id; 00151 bool operator()(Configurable* c) { return c->id == id; } 00152 }; 00153 00154 Configurable(){ id = rand();} 00155 /// intialise with name and revision (use "$ID$") 00156 Configurable(const std::string& name, const std::string& revision) 00157 : name(name), revision(revision) { 00158 id = rand(); 00159 } 00160 virtual ~Configurable(){} 00161 00162 /// return the id of the configurable objects, which is created by random on initialisation 00163 int getId() const { return id;} 00164 00165 00166 /// return the name of the object 00167 virtual paramkey getName() const { 00168 return name; 00169 } 00170 00171 /// returns the revision of the object 00172 virtual paramkey getRevision() const { 00173 return revision; 00174 } 00175 00176 /// stes the name of the object 00177 virtual void setName(const paramkey& name){ 00178 this->name = name; 00179 } 00180 /// sets the revision Hint: { return "$ID$"; } 00181 virtual void getRevision(const paramkey& revision) { 00182 this->revision = revision; 00183 } 00184 00185 /** returns the value of the requested parameter 00186 or 0 (+ error message to stderr) if unknown. 00187 */ 00188 virtual paramval getParam(const paramkey& key) const{ 00189 parammap::const_iterator it = mapOfValues.find(key); 00190 if(it!=mapOfValues.end()){ 00191 return *((*it).second); 00192 }else{ 00193 std::cerr << name << ": "<< __FUNCTION__ << ": parameter " << key << " unknown\n"; 00194 return 0; 00195 } 00196 } 00197 00198 /** sets the value of the given parameter 00199 or does nothing if unknown. 00200 */ 00201 virtual bool setParam(const paramkey& key, paramval val){ 00202 parammap::const_iterator it = mapOfValues.find(key); 00203 if(it!=mapOfValues.end()){ 00204 *(mapOfValues[key]) = val; 00205 return true; 00206 }else{ 00207 return false; // fprintf(stderr, "%s:parameter %s unknown\n", __FUNCTION__, key); 00208 } 00209 } 00210 /** The list of all parameters with there value as allocated lists. 00211 @return list of key-value pairs 00212 */ 00213 virtual paramlist getParamList() const { 00214 return paramlist(); // return an empty list 00215 } 00216 00217 /** 00218 This is the new style for adding configurable parameters. Just call this function 00219 for each parameter and you are done. 00220 If you need to do some special treatment for setting (or getting) of the parameter 00221 you can handle this by overloading getParam and setParam 00222 */ 00223 virtual void addParameter(const paramkey& key, paramval* val){ 00224 mapOfValues[key]=val; 00225 } 00226 00227 /** 00228 This function is only provided for convenience. It does the same as addParameter but set the 00229 variable to the default value 00230 */ 00231 virtual void addParameterDef(const paramkey& key, paramval* val, paramval def){ 00232 *val=def; 00233 mapOfValues[key]=val; 00234 } 00235 00236 /** This is a utility function for inserting the filename and the revision number 00237 at the beginning of the given string buffer str and terminates it. 00238 @param str buffer (call by reference) 00239 that should have space for file+revision+2 characters 00240 @param file filename given by CVS i.e. $RCSfile: configurable.h,v $ 00241 @param revision revision number given by CVS i.e. $Revision: 1.4 $ 00242 */ 00243 static void insertCVSInfo(paramkey& str, const char* file, const char* revision); 00244 00245 /** stores the key values paires into the file : filenamestem.cfg 00246 including the comments given in the list 00247 */ 00248 bool storeCfg(const char* filenamestem, 00249 const std::list< std::string>& comments = std::list< std::string>()); 00250 /** restores the key values paires from the file : filenamestem.cfg */ 00251 bool restoreCfg(const char* filenamestem); 00252 void print(FILE* f, const char* prefix) const; 00253 void parse(FILE* f); 00254 00255 private: 00256 int id; 00257 paramkey name; 00258 paramkey revision; 00259 00260 parammap mapOfValues; 00261 00262 }; 00263 00264 #else 00265 00266 // ATMEL AVR ATMEGA128 code 00267 #include <string.h> 00268 #include "avrtypes.h" 00269 00270 00271 class Configurable { 00272 public: 00273 00274 00275 00276 //pedef std::list< std::pair<paramkey, paramval> > paramlist; 00277 //typedef std::map< paramkey, paramval* > parammap; 00278 00279 /// nice predicate function for finding by ID 00280 /*struct matchId : public std::unary_function<Configurable*, bool> { 00281 matchId(int id) : id(id) {} 00282 int id; 00283 bool operator()(Configurable* c) { return c->id == id; } 00284 }; 00285 */ 00286 00287 Configurable(){ id = rand(); numberParameters=0; } 00288 /// intialise with name and revision (use "$ID$") 00289 Configurable(const paramkey& name, const paramkey& revision) 00290 : name(name), revision(revision) { 00291 id = rand(); 00292 numberParameters=0; 00293 } 00294 virtual ~Configurable(){} 00295 00296 /// return the id of the configurable objects, which is created by random on initialisation 00297 int getId() const { return id;} 00298 00299 00300 /// return the name of the object 00301 virtual paramkey getName() const { 00302 return name; 00303 } 00304 00305 /// returns the revision of the object 00306 virtual paramkey getRevision() const { 00307 return revision; 00308 } 00309 00310 /// stes the name of the object 00311 virtual void setName(const paramkey& name){ 00312 this->name = name; 00313 } 00314 /// sets the revision Hint: { return "$ID$"; } 00315 virtual void getRevision(const paramkey& revision) { 00316 this->revision = revision; 00317 } 00318 00319 /** returns the value of the requested parameter 00320 or 0 (+ error message to stderr) if unknown. 00321 */ 00322 virtual paramval getParam(const paramkey& key) const{ 00323 for (uint8_t i=0;i<maxNumberEntries;i++) { 00324 if (strncmp(key,paramlist[i].key,charLength)==0) 00325 return *(paramlist[i].val); 00326 } 00327 return 0; 00328 } 00329 00330 /** sets the value of the given parameter 00331 or does nothing if unknown. 00332 */ 00333 virtual bool setParam(const paramkey& key, paramval val){ 00334 for (uint8_t i=0;i<maxNumberEntries;i++) { 00335 if (strncmp(key,paramlist[i].key,charLength)==0) 00336 *(paramlist[i].val) = val; 00337 } 00338 return 0; 00339 } 00340 00341 /** The list of all parameters with there value as allocated lists. 00342 @return list of key-value pairs 00343 */ 00344 virtual plist getParamList() const { 00345 return paramlist; 00346 } 00347 00348 /** 00349 This is the new style for adding configurable parameters. Just call this function 00350 for each parameter and you are done. 00351 If you need to do some special treatment for setting (or getting) of the parameter 00352 you can handle this by overloading getParam and setParam 00353 */ 00354 virtual void addParameter(const paramkey& key, paramval* val){ 00355 if (numberParameters<maxNumberEntries) { 00356 paramlist[numberParameters].key=key; 00357 paramlist[numberParameters++].val=val; 00358 } 00359 } 00360 00361 /** 00362 This function is only provided for convenience. It does the same as addParameter but set the 00363 variable to the default value 00364 */ 00365 virtual void addParameterDef(const paramkey& key, paramval* val, paramval def){ 00366 *val=def; 00367 addParameter(key,val); 00368 } 00369 00370 /** This is a utility function for inserting the filename and the revision number 00371 at the beginning of the given string buffer str and terminates it. 00372 @param str buffer (call by reference) 00373 that should have space for file+revision+2 characters 00374 @param file filename given by CVS i.e. $RCSfile: configurable.h,v $ 00375 @param revision revision number given by CVS i.e. $Revision: 1.4 $ 00376 */ 00377 static void insertCVSInfo(paramkey& str, const char* file, const char* revision); 00378 00379 private: 00380 int id; 00381 paramkey name; 00382 paramkey revision; 00383 00384 uint8_t numberParameters; 00385 plist paramlist; 00386 00387 }; 00388 00389 #endif 00390 00391 00392 #endif