// Filename: dconfig.h // Created by: cary (14Jul98) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license // along with this source code; you will also find a current copy of // the license at http://www.panda3d.org/license.txt . // // To contact the maintainers of this program write to // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// #ifndef DCONFIG_H #define DCONFIG_H #include #include "config_setup.h" #include "config_dconfig.h" #include "configTable.h" #include "executionEnvironment.h" #include #include #include namespace Config { // Config is, itself, configurable. The things that can be set are: // path separator ( ': ' ) [pathsep] // filename separator ( / ) [filesep] // config filename ( Configrc ) [configname] // config file suffix ( ) [configsuffix] // config file path ( $CONFIG_PATH ) [configpath] // (can be multiple of these) // config file comment ( '#' ) [configcmt] // 'args' suffix ( _ARGS ) [argsuffix] // command arg env ( CONFIG + _____ ) [commandstub] // debugging output ( false ) [configdbg] // read commandline ( true ) [readargs] // read environment ( true ) [readenv] // all of these can be set from the one unconfigurable thing in config, the // environment variable called CONFIG_CONFIG. The format is: // separator_char{{field_id}={field_value}separator_char}* // Call these functions to get stats on how Config is spending its // time. EXPCL_DTOOLCONFIG INLINE double get_total_time_config_init(); EXPCL_DTOOLCONFIG INLINE double get_total_time_external_init(); EXPCL_DTOOLCONFIG INLINE double get_total_num_get(); // These globals are intended for internal bookkeeping by Config to // compute the above functions' return values. EXPCL_DTOOLCONFIG extern clock_t total_time_config_init; EXPCL_DTOOLCONFIG extern clock_t total_time_external_init; EXPCL_DTOOLCONFIG extern int total_num_get; template class Config { protected: static void ConfigFunc(void); static void Flag(bool); public: Config(void); ~Config(void); static bool AmInitializing(void); static ConfigString Name(void); static bool Flag(void); static void Init(void); static bool Defined(const ConfigString& sym); static ConfigString Get(const ConfigString sym); static ConfigTable::Symbol& GetAll(const ConfigString, ConfigTable::Symbol&); PUBLISHED: static bool GetBool(const ConfigString sym, bool def = false); static int GetInt(const ConfigString sym, int def = 0); static float GetFloat(const ConfigString sym, float def = 0.); static double GetDouble(const ConfigString sym, double def = 0.); static ConfigString GetString(const ConfigString sym, const ConfigString def = ""); }; // Implementation follows template void Config::ConfigFunc(void) { GetConfig::config_func(); } template bool Config::AmInitializing(void) { ConfigTable* tab = ConfigTable::Instance(); if (tab == (ConfigTable *)0L) return Flag(); return tab->AmInitializing(); } template ConfigString Config::Name(void) { return GetConfig::get_name(); } template bool Config::Flag(void) { return GetConfig::_flag; } template void Config::Flag(bool f) { GetConfig::_flag = f; } template void Config::Init(void) { if (Flag()) return; total_time_config_init -= clock(); Flag(true); ConfigTable* tab = ConfigTable::Instance(); if (Defined("notify-level-config")) { ConfigString s = Get("notify-level-config"); NotifySeverity sev = Notify::string_severity(s); if (sev != NS_unspecified) { microconfig_cat->set_severity(sev); dconfig_cat->set_severity(sev); } else { microconfig_cat->set_severity(NS_info); dconfig_cat->set_severity(NS_info); } } else { if(!tab->IsConfigDbg()) { microconfig_cat->set_severity(NS_info); dconfig_cat->set_severity(NS_info); } } total_time_config_init += clock(); total_time_external_init -= clock(); if (dconfig_cat->is_spam()) dconfig_cat->spam() << "calling ConfigFunc for '" << Name() << "'" << endl; ConfigFunc(); if (dconfig_cat->is_spam()) dconfig_cat->spam() << "back from ConfigFunc for '" << Name() << "'" << endl; total_time_external_init += clock(); } template Config::Config(void) { Init(); } template Config::~Config(void) { } template bool Config::Defined(const ConfigString& sym) { Init(); ConfigTable* tab = ConfigTable::Instance(); if (tab->Defined(sym, Name())) return true; else if (tab->Defined(sym, ExecutionEnvironment::get_binary_name())) return true; else if (tab->Defined(sym)) return true; return false; } template ConfigString Config::Get(ConfigString sym) { Init(); ConfigTable* tab = ConfigTable::Instance(); if (tab->Defined(sym, Name())) return (tab->Get(sym, Name())).Val(); else if (tab->Defined(sym, ExecutionEnvironment::get_binary_name())) return (tab->Get(sym, ExecutionEnvironment::get_binary_name())).Val(); else if (tab->Defined(sym)) return (tab->Get(sym)).Val(); else return ""; } template ConfigTable::Symbol& Config::GetAll(const ConfigString sym, ConfigTable::Symbol& s) { Init(); ConfigTable* tab = ConfigTable::Instance(); if (tab->Defined(sym, Name())) { const ConfigTable::Symbol& tsym = tab->GetSym(sym, Name()); s.insert(s.end(), tsym.begin(), tsym.end()); } if (tab->Defined(sym, ExecutionEnvironment::get_binary_name())) { const ConfigTable::Symbol& tsym = tab->GetSym(sym, ExecutionEnvironment::get_binary_name()); s.insert(s.end(), tsym.begin(), tsym.end()); } if (tab->Defined(sym)) { const ConfigTable::Symbol& tsym = tab->GetSym(sym); s.insert(s.end(), tsym.begin(), tsym.end()); } return s; } template bool Config::GetBool(const ConfigString sym, bool def) { Init(); if (Defined(sym)) { ConfigString s = Get(sym); bool ret = ConfigTable::TrueOrFalse(s, def); if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: " << (ret?"true":"false") << endl; return ret; } else { if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' is not defined, returning provided default: " << (def?"true":"false") << endl; return def; } } template int Config::GetInt(const ConfigString sym, int def) { Init(); if (Defined(sym)) { ConfigString v = Get(sym); istringstream s(v); int i; s >> i; if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: " << i << endl; return i; } else { if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' is not defined, returning provided default: " << def << endl; return def; } } template float Config::GetFloat(const ConfigString sym, float def) { Init(); if (Defined(sym)) { ConfigString v = Get(sym); istringstream s(v); float f; s >> f; if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: " << f << endl; return f; } else { if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' is not defined, returning provided default: " << def << endl; return def; } } template double Config::GetDouble(const ConfigString sym, double def) { Init(); if (Defined(sym)) { ConfigString v = Get(sym); istringstream s(v); double d; s >> d; if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: " << d << endl; return d; } else { if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' is not defined, returning provided default: " << def << endl; return def; } } template ConfigString Config::GetString(const ConfigString sym, const ConfigString def) { Init(); if (Defined(sym)) { ConfigString ret = Get(sym); if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' defined, returning: '" << ret << "'" << endl; return ret; } else { if (dconfig_cat->is_spam()) dconfig_cat->spam() << "symbol '" << sym << "' is not defined, returning provided default: '" << def << "'" << endl; return def; } } #include "dconfig.I" } // close Config namespace // Finally, here is a set of handy macros to define and reference a // Configure object in each package. // This macro defines an external reference to a suitable Configure // object; it should appear in the config_*.h file. The config object // will be named name. #if defined(WIN32_VC) && !defined(CPPPARSER) #define ConfigureDecl(name, expcl, exptp) \ class expcl ConfigureGetConfig_ ## name { \ public: \ static const char *get_name(); \ static void config_func(); \ static bool _flag; \ }; \ exptp template class expcl Config::Config; \ extern expcl Config::Config name; #else // WIN32_VC #define ConfigureDecl(name, expcl, exptp) \ class expcl ConfigureGetConfig_ ## name { \ public: \ static const char *get_name(); \ static void config_func(); \ static bool _flag; \ }; \ extern expcl Config::Config name; #endif // WIN32_VC // This macro defines the actual declaration of the Configure object // defined above; it should appear in the config_*.C file. #if defined(PENV_OSX) #define ConfigureDef(name) \ Config::Config name; \ bool ConfigureGetConfig_ ## name::_flag = false; \ int FILE_SYM_NAME = 0; \ const char *ConfigureGetConfig_ ## name:: \ get_name() { \ return #name; \ } #else /* PENV_OSX */ #define ConfigureDef(name) \ Config::Config name; \ bool ConfigureGetConfig_ ## name::_flag = false; \ const char *ConfigureGetConfig_ ## name:: \ get_name() { \ return #name; \ } #endif /* PENV_OSX */ // This macro can be used in lieu of the above two when the Configure // object does not need to be visible outside of the current C file. #if defined(PENV_OSX) #define Configure(name) \ class ConfigureGetConfig_ ## name { \ public: \ static const char *get_name(); \ static void config_func(); \ static bool _flag; \ }; \ static Config::Config name; \ bool ConfigureGetConfig_ ## name::_flag = false; \ int FILE_SYM_NAME = 0; \ const char *ConfigureGetConfig_ ## name:: \ get_name() { \ return #name; \ } #else /* PENV_OSX */ #define Configure(name) \ class ConfigureGetConfig_ ## name { \ public: \ static const char *get_name(); \ static void config_func(); \ static bool _flag; \ }; \ static Config::Config name; \ bool ConfigureGetConfig_ ## name::_flag = false; \ const char *ConfigureGetConfig_ ## name:: \ get_name() { \ return #name; \ } #endif /* PENV_OSX */ // This one defines a block of code that will be executed at static // init time. It must always be defined (in the C file), even if no // code is to be executed. #define ConfigureFn(name) \ void ConfigureGetConfig_ ## name::config_func() #if defined(PENV_OSX) // This is a hack to provide a unique locatable symbol in each lib. #define ConfigureLibSym \ char LIB_SYMBOL_NAME[] = ALL_FILE_SYMS_NAME ; #else #define ConfigureLibSym #endif /* PENV_OSX */ #endif /* __CONFIG_H__ */