
00001 /** 00002 \file Robots/LoBot/config/LoConfig.H 00003 \brief Robolocust/lobot configuration database. 00004 00005 This file defines a class that reads the Robolocust/lobot config file 00006 (~/.lobotrc by default or as specified by the --config-file option) 00007 and then populates a two-level map of key-value pairs that other parts 00008 of the program can use to query whatever parameters they need. 00009 00010 Robolocust/lobot config files are simplified INI files. See 00011 LoIniFileLexer.l and LoIniFileParser.y for the syntax rules and an 00012 illustrative example of what is allowed. 00013 00014 The first level of the two-level map alluded to above corresponds to 00015 sections in the INI file and the second level is for the key-value 00016 pairs of that section. Thus, the first level maps INI file section 00017 names to maps of key-value pairs. These "inner" maps map key names to 00018 their corresponding values. 00019 */ 00020 00021 // //////////////////////////////////////////////////////////////////// // 00022 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00023 // by the University of Southern California (USC) and the iLab at USC. // 00024 // See http://iLab.usc.edu for information about this project. // 00025 // //////////////////////////////////////////////////////////////////// // 00026 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00027 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00028 // in Visual Environments, and Applications'' by Christof Koch and // 00029 // Laurent Itti, California Institute of Technology, 2001 (patent // 00030 // pending; application number 09/912,225 filed July 23, 2001; see // 00031 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00034 // // 00035 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00036 // redistribute it and/or modify it under the terms of the GNU General // 00037 // Public License as published by the Free Software Foundation; either // 00038 // version 2 of the License, or (at your option) any later version. // 00039 // // 00040 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00041 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00042 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00043 // PURPOSE. See the GNU General Public License for more details. // 00044 // // 00045 // You should have received a copy of the GNU General Public License // 00046 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00047 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00048 // Boston, MA 02111-1307 USA. // 00049 // //////////////////////////////////////////////////////////////////// // 00050 // 00051 // Primary maintainer for this file: Manu Viswanathan <mviswana at usc dot edu> 00052 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/config/LoConfig.H $ 00053 // $Id: LoConfig.H 11296 2009-06-12 04:14:27Z mviswana $ 00054 // 00055 00056 #ifndef LOBOT_CONFIGURATION_API_DOT_H 00057 #define LOBOT_CONFIGURATION_API_DOT_H 00058 00059 //------------------------------ HEADERS -------------------------------- 00060 00061 // lobot headers 00062 #include "Robots/LoBot/config/LoLexYaccDefs.H" 00063 00064 #include "Robots/LoBot/misc/LoUtils.H" 00065 #include "Robots/LoBot/misc/LoTypes.H" 00066 #include "Robots/LoBot/misc/singleton.hh" 00067 #include "Robots/LoBot/misc/triple.hh" 00068 #include "Robots/LoBot/misc/range.hh" 00069 00070 // Standard C++ headers 00071 #include <algorithm> 00072 #include <map> 00073 #include <vector> 00074 #include <string> 00075 00076 //------------------------------ DEFINES -------------------------------- 00077 00078 /// The Robolocust config file is divided into multiple sections with 00079 /// each section consisting of key-value pairs. There is a top-level or 00080 /// global section as well that appears before any other sections in the 00081 /// config file. In actuality, this global section is implemented as a 00082 /// specially named section. 00083 /// 00084 /// In addition to the above-mentioned global section of the config file, 00085 /// we also have an internal section that is not meant to be used 00086 /// directly by users. Rather, it acts as a sort of scratch space via 00087 /// which different Robolocust modules can exchange bits of data without 00088 /// having to explicitly know each other (which greatly simplifies the 00089 /// overall design). 00090 /// 00091 /// This internal section is never defined explicitly in the config file. 00092 /// Instead, Robolocust sets it up internally. 00093 #define LOCD_INTERNAL "__SECRET_INTERNAL_SECTION__" 00094 00095 //----------------------------- NAMESPACE ------------------------------- 00096 00097 namespace lobot { 00098 00099 //------------------------- CLASS DEFINITION ---------------------------- 00100 00101 /** 00102 \class lobot::ConfigDB 00103 \brief Robolocust/lobot configuration database. 00104 00105 This class implements a dictionary of key-value pairs. Both keys and 00106 values are strings. 00107 00108 NOTE: This class does not have any public members. It is not meant to 00109 be used directly clients, which should instead use the API provided by 00110 lobot::Configuration. 00111 */ 00112 class Configuration ; // forward declaration 00113 class ConfigDB : public singleton<ConfigDB> { 00114 /// The Robolocust/lobot config file consists of several sections. 00115 /// Each section has key-value statements in it. The configuration 00116 /// database mirrors this structure with a two-level map, i.e., a map 00117 /// of maps. The top-level map maps section names to the collection of 00118 /// key-value definitions in that section. The key-value maps for a 00119 /// section map key names to their corresponding values. 00120 typedef std::map<std::string, std::string> KeyValuePairs ; 00121 typedef std::map<std::string, KeyValuePairs> ConfigMap ; 00122 00123 ConfigMap m_config_db ; 00124 00125 /// Private constructor because the lobot config database is a 00126 /// singleton object. 00127 ConfigDB() ; 00128 friend class singleton<ConfigDB> ; 00129 00130 /// This method inserts the supplied key-value pair into the specified 00131 /// section of the configuration database. 00132 void insert(const std::string& section, 00133 const std::string& key, const std::string& value) ; 00134 00135 /// This method returns the value corresponding to the specified key 00136 /// from the specified section of the configuration database. If the 00137 /// key is not defined, the default value supplied by the client will 00138 /// be returned. 00139 std::string retrieve(const std::string& section, 00140 const std::string& key, 00141 const std::string& default_value) const ; 00142 00143 /// Clean-up 00144 ~ConfigDB() ; 00145 00146 // The configuration database is not accessed directly by clients. 00147 // Instead they use the API provided by the Configuration class, which 00148 // has full access to this object. 00149 friend class Configuration ; 00150 } ; 00151 00152 //------------------------- CLASS DEFINITION ---------------------------- 00153 00154 /** 00155 \class lobot::Configuration 00156 \brief A more user-friendly API for the ConfigDB. 00157 00158 lobot::ConfigDB is an "internal" class related to the lobot config 00159 system and is not meant to be used directly by other objects in the 00160 lobot system. Instead, client modules should use the API provided by 00161 this class for loading and retrieving configuration settings. 00162 */ 00163 class Configuration { 00164 // prevent instantiation, copy and assignment 00165 Configuration() ; 00166 Configuration(const Configuration&) ; 00167 Configuration& operator=(const Configuration&) ; 00168 00169 public: 00170 /// This method loads the configuration settings from the specified 00171 /// file. 00172 static void load(const std::string& config_file) ; 00173 00174 /// This method inserts the supplied key-value pair into the specified 00175 /// section of the configuration database. 00176 static void set(const std::string& section, 00177 const std::string& key, const std::string& value) ; 00178 00179 /// This method inserts the supplied key-value pair into the 00180 /// unnamed/anonymous global/top-level scope of the configuration 00181 /// database. 00182 static void set_global(const std::string& key, const std::string& value) ; 00183 00184 /// This method inserts the supplied key-value pair into the (secret) 00185 /// internal section of the configuration database. 00186 static void set_internal(const std::string& key, const std::string& value) ; 00187 00188 /// This method retrieves the value corresponding to the specified key 00189 /// from the specified section of the configuration database. If the 00190 /// key is not defined, the default value supplied by the client will 00191 /// be returned. 00192 template<typename T> 00193 static T get(const std::string& section, const std::string& key, 00194 const T& default_value = T()) ; 00195 00196 /// The configuration database simply retains key-value pairs as 00197 /// strings. But some settings can be lists (e.g., the value 00198 /// corresponding to some key may be a list of numbers). This method 00199 /// "breaks up" the value portion of the specified key and section 00200 /// into a list and returns the result via an array of type T. 00201 template<typename T> 00202 static void get(const std::string& section, const std::string& key, 00203 T* target, const T* defaults, unsigned int n) ; 00204 00205 /// This method retrieves the value corresponding to the specified key 00206 /// from the unnamed/anonymous global/top-level scope section of the 00207 /// configuration database. If the key is not defined in the top-level 00208 /// section, the default value supplied by the client will be 00209 /// returned. 00210 template<typename T> 00211 static T get_global(const std::string& key, const T& defval = T()) ; 00212 00213 /// Development and debugging support 00214 static void dump() ; 00215 } ; 00216 00217 /// Retrieve the value corresponding to the specified key from the 00218 /// specified section of the config file and return it as an instance of 00219 /// type T. 00220 template<typename T> 00221 T Configuration::get(const std::string& section, const std::string& key, 00222 const T& default_value) 00223 { 00224 std::string value = ConfigDB::instance().retrieve(section, key, "") ; 00225 if (value == "") //key-value pair not defined in specified sec. of INI file 00226 return default_value ; 00227 return from_string<T>(value) ; 00228 } 00229 00230 /// Partial specialization of above method for retrieving on/off/yes/no 00231 /// flags from the config file. 00232 template<> 00233 bool Configuration::get(const std::string& section, const std::string& key, 00234 const bool& default_value) 00235 { 00236 std::string flag = 00237 downstring(ConfigDB::instance().retrieve(section, key, "")) ; 00238 if (flag == "") // not defined in config file 00239 return default_value ; 00240 if (flag == "f" || flag == "false" || flag == "no" || flag == "off" || 00241 flag == "0" || flag == "disabled") 00242 return false ; 00243 return true ; 00244 } 00245 00246 /// Retrieve the values corresponding to the specified key from the 00247 /// specified section of the config file and return them via an array of 00248 /// type T. 00249 template<typename T> 00250 void Configuration::get(const std::string& section, const std::string& key, 00251 T* target, const T* defaults, unsigned int n) 00252 { 00253 std::copy(defaults, defaults + n, target) ; 00254 std::vector<T> config(string_to_vector<T>(get<std::string>(section, key))) ; 00255 if (config.size() > n) 00256 config.resize(n) ; 00257 std::copy(config.begin(), config.end(), target) ; 00258 } 00259 00260 /// This method retrieves the value corresponding to the specified key 00261 /// from the unnamed/anonymous global/top-level scope section of the 00262 /// configuration database. If the key is not defined in the top-level 00263 /// section, the default value supplied by the client will be returned. 00264 template<typename T> 00265 T Configuration::get_global(const std::string& key, const T& defval) 00266 { 00267 return get<T>(LOCD_TOP_LEVEL, key, defval) ; 00268 } 00269 00270 //-------------------- LOBOT CONFIGURATION HELPERS ---------------------- 00271 00272 /// A convenience routine to allow clients to not have to type the whole 00273 /// Configuration::get call... 00274 template<typename T> 00275 inline T get_conf(const std::string& section, const std::string& key, 00276 const T& default_value = T()) 00277 { 00278 return Configuration::get(section, key, default_value) ; 00279 } 00280 00281 /// A convenience routine to return an RGB color from the specified 00282 /// section of the config file. 00283 template<> 00284 PixelType get_conf(const std::string& section, const std::string& key, 00285 const PixelType& defval) 00286 { 00287 int color[3] ; 00288 const int default_color[] = {defval.red(), defval.green(), defval.blue()} ; 00289 Configuration::get(section, key, color, default_color, 3) ; 00290 return PixelType(color[0], color[1], color[2]) ; 00291 } 00292 00293 /// Convenience routine to return a range<T> from the specified section 00294 /// of the config file. 00295 template<typename T> 00296 range<T> get_conf(const std::string& section, const std::string& key, 00297 const range<T>& defval = range<T>(T(), T())) 00298 { 00299 T range[2] ; 00300 const T defaults[] = {defval.min(), defval.max()} ; 00301 Configuration::get<T>(section, key, range, defaults, 2) ; 00302 return make_range(range[0], range[1]) ; 00303 } 00304 00305 /// Convenience routine to return a triple from the specified section of 00306 /// the config file. 00307 template<typename T> 00308 triple<T, T, T> 00309 get_conf(const std::string& section, const std::string& key, 00310 const triple<T, T, T>& defval = make_triple(T(), T(), T())) 00311 { 00312 T triple[3] ; 00313 const T defaults[] = {defval.first, defval.second, defval.third} ; 00314 Configuration::get<T>(section, key, triple, defaults, 3) ; 00315 return make_triple(triple[0], triple[1], triple[2]) ; 00316 } 00317 00318 /// Retrieve settings from the video section of the config file 00319 template<typename T> 00320 inline T video_conf(const std::string& key, const T& default_value = T()) 00321 { 00322 return get_conf<T>("video", key, default_value) ; 00323 } 00324 00325 /// Retrieve settings from the laser section of the config file 00326 template<typename T> 00327 inline T laser_conf(const std::string& key, const T& default_value = T()) 00328 { 00329 return get_conf<T>("laser", key, default_value) ; 00330 } 00331 00332 /// Retrieve settings from the motor section of the config file 00333 template<typename T> 00334 inline T motor_conf(const std::string& key, const T& default_value = T()) 00335 { 00336 return get_conf<T>("motor", key, default_value) ; 00337 } 00338 00339 /// Retrieve settings from the optical flow section of the config file 00340 template<typename T> 00341 inline T optical_flow_conf(const std::string& key, const T& default_value) 00342 { 00343 return get_conf<T>("optical_flow", key, default_value) ; 00344 } 00345 00346 /// Retrieve settings from the ui section of the config file 00347 template<typename T> 00348 inline T ui_conf(const std::string& key, const T& default_value = T()) 00349 { 00350 return get_conf<T>("ui", key, default_value) ; 00351 } 00352 00353 /// Retrieve settings from the global section of the config file 00354 template<typename T> 00355 inline T global_conf(const std::string& key, const T& default_value = T()) 00356 { 00357 return Configuration::get_global<T>(key, default_value) ; 00358 } 00359 00360 /// Retrieve settings from the secret internal section of the 00361 /// configuration database. 00362 template<typename T> 00363 inline T internal_conf(const std::string& key, const T& default_value = T()) 00364 { 00365 return get_conf<T>(LOCD_INTERNAL, key, default_value) ; 00366 } 00367 00368 //----------------------------------------------------------------------- 00369 00370 } // end of namespace encapsulating this file's definitions 00371 00372 #endif 00373 00374 /* So things look consistent in everyone's emacs... */ 00375 /* Local Variables: */ 00376 /* indent-tabs-mode: nil */ 00377 /* End: */
1.4.4