Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/dconfig/dconfig.h

Go to the documentation of this file.
00001 // Filename: dconfig.h
00002 // Created by:  cary (14Jul98)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef DCONFIG_H
00020 #define DCONFIG_H
00021 
00022 #include <dtoolbase.h>
00023 
00024 #include "config_setup.h"
00025 #include "config_dconfig.h"
00026 #include "configTable.h"
00027 #include "executionEnvironment.h"
00028 
00029 #include <vector>
00030 #include <map>
00031 #include <time.h>
00032 
00033 namespace Config {
00034 
00035 // Config is, itself, configurable.  The things that can be set are:
00036 //    path separator      ( ': ' ) [pathsep]
00037 //    filename separator  ( / ) [filesep]
00038 //    config filename     ( Configrc ) [configname]
00039 //    config file suffix  ( ) [configsuffix]
00040 //    config file path    ( $CONFIG_PATH ) [configpath]
00041 //        (can be multiple of these)
00042 //    config file comment ( '#' ) [configcmt]
00043 //    'args' suffix       ( _ARGS ) [argsuffix]
00044 //    command arg env     ( CONFIG + _____ ) [commandstub]
00045 //    debugging output    ( false ) [configdbg]
00046 //    read commandline    ( true ) [readargs]
00047 //    read environment    ( true ) [readenv]
00048 // all of these can be set from the one unconfigurable thing in config, the
00049 // environment variable called CONFIG_CONFIG.  The format is:
00050 //    separator_char{{field_id}={field_value}separator_char}*
00051 
00052 // Call these functions to get stats on how Config is spending its
00053 // time.
00054 EXPCL_DTOOLCONFIG INLINE double get_total_time_config_init();
00055 EXPCL_DTOOLCONFIG INLINE double get_total_time_external_init();
00056 EXPCL_DTOOLCONFIG INLINE double get_total_num_get();
00057 
00058 // These globals are intended for internal bookkeeping by Config to
00059 // compute the above functions' return values.
00060 EXPCL_DTOOLCONFIG extern clock_t total_time_config_init;
00061 EXPCL_DTOOLCONFIG extern clock_t total_time_external_init;
00062 EXPCL_DTOOLCONFIG extern int total_num_get;
00063 
00064 template <class GetConfig>
00065 class Config {
00066    protected:
00067       static void ConfigFunc(void);
00068       static void Flag(bool);
00069    public:
00070       Config(void);
00071       ~Config(void);
00072       static bool         AmInitializing(void);
00073       static ConfigString Name(void);
00074       static bool         Flag(void);
00075       static void         Init(void);
00076       static bool         Defined(const ConfigString& sym);
00077       static ConfigString Get(const ConfigString sym);
00078       static ConfigTable::Symbol& GetAll(const ConfigString,
00079                                          ConfigTable::Symbol&);
00080    PUBLISHED:
00081       static bool         GetBool(const ConfigString sym, bool def = false);
00082       static int          GetInt(const ConfigString sym, int def = 0);
00083       static float        GetFloat(const ConfigString sym, float def = 0.);
00084       static double       GetDouble(const ConfigString sym, double def = 0.);
00085       static ConfigString GetString(const ConfigString sym,
00086                                     const ConfigString def = "");
00087 };
00088 
00089 // Implementation follows
00090 
00091 template<class GetConfig>
00092 void Config<GetConfig>::ConfigFunc(void)
00093 {
00094   GetConfig::config_func();
00095 }
00096 
00097 template<class GetConfig>
00098 bool Config<GetConfig>::AmInitializing(void)
00099 {
00100    ConfigTable* tab = ConfigTable::Instance();
00101    if (tab == (ConfigTable *)0L)
00102       return Flag();
00103    return tab->AmInitializing();
00104 }
00105 
00106 template<class GetConfig>
00107 ConfigString Config<GetConfig>::Name(void)
00108 {
00109    return GetConfig::get_name();
00110 }
00111 
00112 template<class GetConfig>
00113 bool Config<GetConfig>::Flag(void)
00114 {
00115    return GetConfig::_flag;
00116 }
00117 
00118 template<class GetConfig>
00119 void Config<GetConfig>::Flag(bool f)
00120 {
00121    GetConfig::_flag = f;
00122 }
00123 
00124 template<class GetConfig>
00125 void Config<GetConfig>::Init(void)
00126 {
00127    if (Flag())
00128       return;
00129    total_time_config_init -= clock();
00130    Flag(true);
00131    ConfigTable* tab = ConfigTable::Instance();
00132 
00133    if (Defined("notify-level-config")) {
00134       ConfigString s = Get("notify-level-config");
00135       NotifySeverity sev = Notify::string_severity(s);
00136       if (sev != NS_unspecified) {
00137          microconfig_cat->set_severity(sev);
00138          dconfig_cat->set_severity(sev);
00139       } else {
00140          microconfig_cat->set_severity(NS_info);
00141          dconfig_cat->set_severity(NS_info);
00142       }
00143    } else {
00144       if(!tab->IsConfigDbg()) {
00145           microconfig_cat->set_severity(NS_info);
00146           dconfig_cat->set_severity(NS_info);
00147       }
00148    }
00149 
00150    total_time_config_init += clock();
00151    total_time_external_init -= clock();
00152 
00153    if (dconfig_cat->is_spam())
00154       dconfig_cat->spam() << "calling ConfigFunc for '" << Name() << "'"
00155                          << endl;
00156    ConfigFunc();
00157    if (dconfig_cat->is_spam())
00158       dconfig_cat->spam() << "back from ConfigFunc for '" << Name() << "'"
00159                          << endl;
00160    total_time_external_init += clock();
00161 }
00162 
00163 template<class GetConfig>
00164 Config<GetConfig>::Config(void)
00165 {
00166    Init();
00167 }
00168 
00169 template<class GetConfig>
00170 Config<GetConfig>::~Config(void)
00171 {
00172 }
00173 
00174 template<class GetConfig>
00175 bool Config<GetConfig>::Defined(const ConfigString& sym)
00176 {
00177    Init();
00178    ConfigTable* tab = ConfigTable::Instance();
00179    if (tab->Defined(sym, Name()))
00180       return true;
00181    else if (tab->Defined(sym, ExecutionEnvironment::get_binary_name()))
00182       return true;
00183    else if (tab->Defined(sym))
00184       return true;
00185    return false;
00186 }
00187 
00188 template<class GetConfig>
00189 ConfigString Config<GetConfig>::Get(ConfigString sym)
00190 {
00191    Init();
00192    ConfigTable* tab = ConfigTable::Instance();
00193    if (tab->Defined(sym, Name()))
00194       return (tab->Get(sym, Name())).Val();
00195    else if (tab->Defined(sym, ExecutionEnvironment::get_binary_name()))
00196       return (tab->Get(sym, ExecutionEnvironment::get_binary_name())).Val();
00197    else if (tab->Defined(sym))
00198       return (tab->Get(sym)).Val();
00199    else
00200       return "";
00201 }
00202 
00203 template<class GetConfig>
00204 ConfigTable::Symbol& Config<GetConfig>::GetAll(const ConfigString sym,
00205                                                 ConfigTable::Symbol& s)
00206 {
00207    Init();
00208    ConfigTable* tab = ConfigTable::Instance();
00209    if (tab->Defined(sym, Name())) {
00210      const ConfigTable::Symbol& tsym = tab->GetSym(sym, Name());
00211      s.insert(s.end(), tsym.begin(), tsym.end());
00212    }
00213    if (tab->Defined(sym, ExecutionEnvironment::get_binary_name())) {
00214      const ConfigTable::Symbol& tsym = tab->GetSym(sym, ExecutionEnvironment::get_binary_name());
00215      s.insert(s.end(), tsym.begin(), tsym.end());
00216    }
00217    if (tab->Defined(sym)) {
00218      const ConfigTable::Symbol& tsym = tab->GetSym(sym);
00219      s.insert(s.end(), tsym.begin(), tsym.end());
00220    }
00221    return s;
00222 }
00223 
00224 template<class GetConfig>
00225 bool Config<GetConfig>::GetBool(const ConfigString sym, bool def)
00226 {
00227    Init();
00228    if (Defined(sym)) {
00229       ConfigString s = Get(sym);
00230       bool ret = ConfigTable::TrueOrFalse(s, def);
00231       if (dconfig_cat->is_spam())
00232          dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: "
00233                             << (ret?"true":"false") << endl;
00234       return ret;
00235    } else {
00236       if (dconfig_cat->is_spam())
00237          dconfig_cat->spam()
00238             << "symbol '" << sym
00239             << "' is not defined, returning provided default: "
00240             << (def?"true":"false") << endl;
00241       return def;
00242    }
00243 }
00244 
00245 template<class GetConfig>
00246 int Config<GetConfig>::GetInt(const ConfigString sym, int def)
00247 {
00248    Init();
00249    if (Defined(sym)) {
00250       ConfigString v = Get(sym);
00251       istringstream s(v);
00252       int i;
00253       s >> i;
00254       if (dconfig_cat->is_spam())
00255          dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: "
00256                             << i << endl;
00257       return i;
00258    } else {
00259       if (dconfig_cat->is_spam())
00260          dconfig_cat->spam()
00261             << "symbol '" << sym
00262             << "' is not defined, returning provided default: " << def << endl;
00263       return def;
00264    }
00265 }
00266 
00267 template<class GetConfig>
00268 float Config<GetConfig>::GetFloat(const ConfigString sym, float def)
00269 {
00270    Init();
00271    if (Defined(sym)) {
00272       ConfigString v = Get(sym);
00273       istringstream s(v);
00274       float f;
00275       s >> f;
00276       if (dconfig_cat->is_spam())
00277          dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: "
00278                             << f << endl;
00279       return f;
00280    } else {
00281       if (dconfig_cat->is_spam())
00282          dconfig_cat->spam()
00283             << "symbol '" << sym
00284             << "' is not defined, returning provided default: " << def << endl;
00285       return def;
00286    }
00287 }
00288 
00289 template<class GetConfig>
00290 double Config<GetConfig>::GetDouble(const ConfigString sym, double def)
00291 {
00292    Init();
00293    if (Defined(sym)) {
00294       ConfigString v = Get(sym);
00295       istringstream s(v);
00296       double d;
00297       s >> d;
00298       if (dconfig_cat->is_spam())
00299          dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: "
00300                             << d << endl;
00301       return d;
00302    } else {
00303       if (dconfig_cat->is_spam())
00304          dconfig_cat->spam()
00305             << "symbol '" << sym
00306             << "' is not defined, returning provided default: " << def << endl;
00307       return def;
00308    }
00309 }
00310 
00311 template<class GetConfig>
00312 ConfigString Config<GetConfig>::GetString(const ConfigString sym,
00313                                            const ConfigString def)
00314 {
00315    Init();
00316    if (Defined(sym)) {
00317       ConfigString ret = Get(sym);
00318       if (dconfig_cat->is_spam())
00319          dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: '"
00320                             << ret << "'" << endl;
00321       return ret;
00322    } else {
00323       if (dconfig_cat->is_spam())
00324          dconfig_cat->spam()
00325             << "symbol '" << sym
00326             << "' is not defined, returning provided default: '" << def
00327             << "'" << endl;
00328       return def;
00329    }
00330 }
00331 
00332 #include "dconfig.I"
00333 
00334 } // close Config namespace
00335 
00336 
00337 // Finally, here is a set of handy macros to define and reference a
00338 // Configure object in each package.
00339 
00340 // This macro defines an external reference to a suitable Configure
00341 // object; it should appear in the config_*.h file.  The config object
00342 // will be named name.
00343 
00344 #if defined(WIN32_VC) && !defined(CPPPARSER)
00345 
00346 #define ConfigureDecl(name, expcl, exptp) \
00347   class expcl ConfigureGetConfig_ ## name { \
00348   public: \
00349     static const char *get_name(); \
00350     static void config_func(); \
00351     static bool _flag; \
00352   }; \
00353   exptp template class expcl Config::Config<ConfigureGetConfig_ ## name>; \
00354   extern expcl Config::Config<ConfigureGetConfig_ ## name> name;
00355 
00356 #else // WIN32_VC
00357 
00358 #define ConfigureDecl(name, expcl, exptp) \
00359   class expcl ConfigureGetConfig_ ## name { \
00360   public: \
00361     static const char *get_name(); \
00362     static void config_func(); \
00363     static bool _flag; \
00364   }; \
00365   extern expcl Config::Config<ConfigureGetConfig_ ## name> name;
00366 
00367 #endif  // WIN32_VC
00368 
00369 // This macro defines the actual declaration of the Configure object
00370 // defined above; it should appear in the config_*.C file.
00371 
00372 #if defined(PENV_OSX)
00373 #define ConfigureDef(name) \
00374   Config::Config<ConfigureGetConfig_ ## name> name; \
00375   bool ConfigureGetConfig_ ## name::_flag = false; \
00376   int FILE_SYM_NAME = 0; \
00377   const char *ConfigureGetConfig_ ## name:: \
00378   get_name() { \
00379     return #name; \
00380   }
00381 #else  /* PENV_OSX */
00382 #define ConfigureDef(name) \
00383   Config::Config<ConfigureGetConfig_ ## name> name; \
00384   bool ConfigureGetConfig_ ## name::_flag = false; \
00385   const char *ConfigureGetConfig_ ## name:: \
00386   get_name() { \
00387     return #name; \
00388   }
00389 #endif /* PENV_OSX */
00390 
00391 // This macro can be used in lieu of the above two when the Configure
00392 // object does not need to be visible outside of the current C file.
00393 
00394 #if defined(PENV_OSX)
00395 #define Configure(name) \
00396   class ConfigureGetConfig_ ## name { \
00397   public: \
00398     static const char *get_name(); \
00399     static void config_func(); \
00400     static bool _flag; \
00401   }; \
00402   static Config::Config<ConfigureGetConfig_ ## name> name; \
00403   bool ConfigureGetConfig_ ## name::_flag = false; \
00404   int FILE_SYM_NAME = 0; \
00405   const char *ConfigureGetConfig_ ## name:: \
00406   get_name() { \
00407     return #name; \
00408   }
00409 #else  /* PENV_OSX */
00410 #define Configure(name) \
00411   class ConfigureGetConfig_ ## name { \
00412   public: \
00413     static const char *get_name(); \
00414     static void config_func(); \
00415     static bool _flag; \
00416   }; \
00417   static Config::Config<ConfigureGetConfig_ ## name> name; \
00418   bool ConfigureGetConfig_ ## name::_flag = false; \
00419   const char *ConfigureGetConfig_ ## name:: \
00420   get_name() { \
00421     return #name; \
00422   }
00423 #endif /* PENV_OSX */
00424 
00425 // This one defines a block of code that will be executed at static
00426 // init time.  It must always be defined (in the C file), even if no
00427 // code is to be executed.
00428 
00429 #define ConfigureFn(name) \
00430   void ConfigureGetConfig_ ## name::config_func()
00431 
00432 #if defined(PENV_OSX)
00433 // This is a hack to provide a unique locatable symbol in each lib.
00434 #define ConfigureLibSym \
00435   char LIB_SYMBOL_NAME[] = ALL_FILE_SYMS_NAME ;
00436 #else
00437 #define ConfigureLibSym
00438 #endif /* PENV_OSX */
00439 
00440 #endif /* __CONFIG_H__ */

Generated on Thu May 1 22:12:57 2003 for DTool by doxygen1.3