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.9 2010/03/03 14:56:30 martius 00028 * improved printing of parameterdescription 00029 * 00030 * Revision 1.8 2009/08/05 22:47:10 martius 00031 * added support for integer variables and 00032 * proper display for bool and int 00033 * 00034 * Revision 1.7 2009/08/05 08:36:22 guettler 00035 * added support for boolean variables 00036 * 00037 * Revision 1.6 2009/03/27 06:16:57 guettler 00038 * support for gcc 4.3 compatibility (has to be checked), StatisticTools moves from utils to statistictools 00039 * 00040 * Revision 1.5 2008/11/14 09:16:15 martius 00041 * small things 00042 * 00043 * Revision 1.4 2008/08/14 08:06:02 robot1 00044 * fixed compile bug 00045 * 00046 * Revision 1.3 2008/08/01 14:42:03 guettler 00047 * we try the trip to hell! make selforg AVR compatible...good luck (first changes) 00048 * 00049 * Revision 1.2 2008/04/29 07:41:40 guettler 00050 * added GPL and revision tag 00051 * 00052 * Revision 1.1 2008/04/29 07:39:54 guettler 00053 * interfaces moved to selforg/utils directory 00054 * 00055 * Revision 1.7 2008/04/11 14:12:30 martius 00056 * comments paramter in storeCfg 00057 * 00058 * Revision 1.6 2007/06/08 15:44:32 martius 00059 * termination string -> more robust parsing 00060 * 00061 * Revision 1.5 2007/03/26 13:13:47 martius 00062 * store and restore with params 00063 * 00064 * Revision 1.4 2007/01/24 14:38:35 martius 00065 * new implementation with a map from key to reference. 00066 * addParameter and addParameterDef are used for registration of a parameter 00067 * the old style is still supported 00068 * 00069 * Revision 1.3 2006/07/14 12:23:57 martius 00070 * selforg becomes HEAD 00071 * 00072 * Revision 1.1.2.7 2006/06/25 21:56:07 martius 00073 * configureable has name and revision 00074 * 00075 * Revision 1.1.2.6 2006/02/08 16:17:40 martius 00076 * no namespace using 00077 * 00078 * Revision 1.1.2.5 2006/01/18 16:48:10 martius 00079 * configurables can be stored and reloaded 00080 * 00081 * Revision 1.1.2.4 2006/01/18 10:45:32 martius 00082 * *** empty log message *** 00083 * 00084 * Revision 1.1.2.3 2006/01/18 10:44:49 martius 00085 * (re)storeCfg 00086 * 00087 * Revision 1.1.2.2 2006/01/16 17:40:13 martius 00088 * parsing works 00089 * 00090 * Revision 1.1.2.1 2006/01/16 17:27:17 martius 00091 * *** empty log message *** 00092 * 00093 * * 00094 ***************************************************************************/ 00095 #ifndef __CONFIGURABLE_H 00096 #define __CONFIGURABLE_H 00097 00098 #include <iostream> 00099 #include <cstdlib> 00100 00101 #include <list> 00102 #include <utility> 00103 #include <string> 00104 #include <map> 00105 #include "stl_adds.h" 00106 00107 /** 00108 Abstact class for configurable objects. Sort of Hashmap interface. Parameters are double, int or boolean values 00109 00110 The Configurator is a (planned) external tool that can be used for changing the values of configurable objects. 00111 00112 * Protocoll for Configurator: 00113 \code 00114 To Configurator (BNF notation): 00115 Conf := <Comp>* 00116 Comp := <CompName> <Pair>* 00117 CompName := [<string>][<int>]<newline> 00118 Pair := <alphanum>=<double><newline> 00119 \endcode 00120 the remaining tags are self explanatory 00121 00122 Example 00123 \code 00124 [Component name which can contain spaces and digits and .,- ][ID1] 00125 key1 = value1 00126 key2 = value2 00127 . 00128 . 00129 [Other Component name which can contain spaces and digits and .,- ][ID2] 00130 key3 = value3 00131 \endcode 00132 00133 Answer: (from Communicator to Simulation environment)\n 00134 1. On change of a parameter: 00135 \code 00136 [ID] key=newvalue 00137 \endcode 00138 or 00139 \code 00140 key=newvalue 00141 \endcode 00142 the latter one means that the parameter is changed in all components 00143 00144 2. Request of the description as defined above. 00145 \code 00146 #Something I don\'t care 00147 \endcode 00148 */ 00149 00150 class Configurable 00151 { 00152 public: 00153 00154 typedef std::string paramkey; 00155 typedef std::string paramdescr; 00156 // params of type double 00157 typedef double paramval; 00158 typedef std::list<std::pair<paramkey, paramval> > paramlist; 00159 typedef std::map<paramkey, paramval*> parammap; 00160 00161 // params of type bool 00162 typedef bool parambool; 00163 typedef std::list<std::pair<paramkey, parambool> > paramboollist; 00164 typedef std::map<paramkey, parambool*> paramboolmap; 00165 00166 // params of type int 00167 typedef int paramint; 00168 typedef std::list<std::pair<paramkey, paramint> > paramintlist; 00169 typedef std::map<paramkey, paramint*> paramintmap; 00170 00171 typedef std::map<paramkey, paramdescr> paramdescrmap; 00172 00173 /// nice predicate function for finding by ID 00174 struct matchId : public std::unary_function<Configurable*, bool> 00175 { 00176 matchId(int id) : 00177 id(id) 00178 { 00179 } 00180 int id; 00181 bool operator()(Configurable* c) 00182 { 00183 return c->id == id; 00184 } 00185 }; 00186 00187 Configurable() 00188 { 00189 id = rand(); 00190 } 00191 /// intialise with name and revision (use "$ID$") 00192 Configurable(const std::string& name, const std::string& revision) : 00193 name(name), revision(revision) 00194 { 00195 id = rand(); 00196 } 00197 00198 // Configurable(const Configurable& copy) 00199 // :id(copy.id), name(copy.name), revision(revision), 00200 // mapOfValues(mapOfValues), mapOfBoolean(mapOfBoolean), mapOfInteger(mapOfInteger) 00201 // { 00202 // } 00203 00204 00205 virtual ~Configurable() 00206 { 00207 } 00208 00209 /// return the id of the configurable objects, which is created by random on initialisation 00210 int getId() const { 00211 return id; 00212 } 00213 00214 /// return the name of the object 00215 virtual paramkey getName() const { 00216 return name; 00217 } 00218 00219 /// returns the revision of the object 00220 virtual paramkey getRevision() const { 00221 return revision; 00222 } 00223 00224 /// stes the name of the object 00225 virtual void setName(const paramkey& name){ 00226 this->name = name; 00227 } 00228 /// sets the revision Hint: { return "$ID$"; } 00229 virtual void setRevision(const paramkey& revision) { 00230 this->revision = revision; 00231 } 00232 00233 /** returns the value of the requested parameter 00234 or 0 (+ error message to stderr) if unknown. 00235 */ 00236 virtual paramval getParam(const paramkey& key) const; 00237 00238 /** sets the value of the given parameter 00239 or does nothing if unknown. 00240 */ 00241 virtual bool setParam(const paramkey& key, paramval val); 00242 00243 /** The list of all parameters with there value as allocated lists. 00244 Note that these are only parameters that are managed manually (with setParam, getParam) 00245 @see getAllParamNames() 00246 @return list of key-value pairs 00247 */ 00248 virtual paramlist getParamList() const { 00249 return paramlist(); // return an empty list 00250 } 00251 00252 /// returns all names that are configureable 00253 virtual std::list<paramkey> getAllParamNames(); 00254 00255 /// returns the description for the given parameter 00256 virtual paramdescr getParamDescr(const paramkey& key) const; 00257 00258 /// sets a description for the given parameter 00259 virtual void setParamDescr(const paramkey& key, const paramdescr& descr) { 00260 if(!descr.empty()) mapOfDescr[key] = descr; 00261 } 00262 00263 /** 00264 This is the new style for adding configurable parameters. Just call this function 00265 for each parameter and you are done. 00266 If you need to do some special treatment for setting (or getting) of the parameter 00267 you can handle this by overloading getParam and setParam 00268 */ 00269 virtual void addParameter(const paramkey& key, paramval* val, 00270 const paramdescr& descr = paramdescr()) { 00271 mapOfValues[key] = val; 00272 if(!descr.empty()) mapOfDescr[key] = descr; 00273 } 00274 00275 /** 00276 See addParameter(const paramkey& key, paramval* val) but for bool values 00277 */ 00278 virtual void addParameter(const paramkey& key, parambool* val, 00279 const paramdescr& descr = paramdescr()) { 00280 mapOfBoolean[key] = val; 00281 if(!descr.empty()) mapOfDescr[key] = descr; 00282 } 00283 00284 /** 00285 See addParameter(const paramkey& key, paramval* val) but for int values 00286 */ 00287 virtual void addParameter(const paramkey& key, paramint* val, 00288 const paramdescr& descr = paramdescr()) { 00289 mapOfInteger[key] = val; 00290 if(!descr.empty()) mapOfDescr[key] = descr; 00291 } 00292 00293 /** 00294 This function is only provided for convenience. It does the same as addParameter but set the 00295 variable to the default value 00296 */ 00297 virtual void addParameterDef(const paramkey& key, paramval* val, paramval def, 00298 const paramdescr& descr = paramdescr()){ 00299 *val = def; 00300 addParameter(key,val,descr); 00301 } 00302 00303 /// See addParameterDef(const paramkey&, paramval*, paramval) 00304 virtual void addParameterDef(const paramkey& key, parambool* val, parambool def, 00305 const paramdescr& descr = paramdescr()) { 00306 *val = def; 00307 addParameter(key,val,descr); 00308 } 00309 00310 /// See addParameterDef(const paramkey&, paramval*, paramval) 00311 virtual void addParameterDef(const paramkey& key, paramint* val, paramint def, 00312 const paramdescr& descr = paramdescr()) { 00313 *val = def; 00314 addParameter(key,val,descr); 00315 } 00316 00317 00318 /** This is a utility function for inserting the filename and the revision number 00319 at the beginning of the given string buffer str and terminates it. 00320 @param str buffer (call by reference) 00321 that should have space for file+revision+2 characters 00322 @param file filename given by CVS i.e. $RCSfile: configurable.h,v $ 00323 @param revision revision number given by CVS i.e. $Revision: 1.9 $ 00324 */ 00325 static void insertCVSInfo(paramkey& str, const char* file, const char* revision); 00326 00327 /** stores the key values paires into the file : filenamestem.cfg 00328 including the comments given in the list 00329 */ 00330 virtual bool storeCfg(const char* filenamestem, const std::list<std::string>& comments = std::list<std::string>()); 00331 /** restores the key values paires from the file : filenamestem.cfg */ 00332 virtual bool restoreCfg(const char* filenamestem); 00333 /// prints the keys, values and descriptions to the file. Each line is prefixed 00334 void print(FILE* f, const char* prefix, int columns=90) const; 00335 // internal function to print only description in multiline fasion 00336 void printdescr(FILE* f, const char* prefix, const paramkey& key, 00337 int columns, int indent) const; 00338 00339 void parse(FILE* f); 00340 00341 private: 00342 int id; 00343 paramkey name; 00344 paramkey revision; 00345 00346 parammap mapOfValues; 00347 paramboolmap mapOfBoolean; 00348 paramintmap mapOfInteger; 00349 paramdescrmap mapOfDescr; 00350 }; 00351 00352 #endif // __CONFIGURABLE_H