open_toontown_panda3d/dtool/src/dconfig/dconfig.h

425 lines
12 KiB
C++

// Filename: dconfig.h
// Created by: cary (14Jul98)
//
///////////////////////////////////////////////////////////////////////
#ifndef DCONFIG_H
#define DCONFIG_H
#include <dtoolbase.h>
#include "config_setup.h"
#include "config_dconfig.h"
#include "configTable.h"
#include "executionEnvironment.h"
#include <vector>
#include <map>
#include <time.h>
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_DTOOL INLINE double get_total_time_config_init();
EXPCL_DTOOL INLINE double get_total_time_external_init();
EXPCL_DTOOL INLINE double get_total_num_get();
// These globals are intended for internal bookkeeping by Config to
// compute the above functions' return values.
EXPCL_DTOOL extern clock_t total_time_config_init;
EXPCL_DTOOL extern clock_t total_time_external_init;
EXPCL_DTOOL extern int total_num_get;
template <class GetConfig>
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&);
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<class GetConfig>
void Config<GetConfig>::ConfigFunc(void)
{
GetConfig::config_func();
}
template<class GetConfig>
bool Config<GetConfig>::AmInitializing(void)
{
ConfigTable* tab = ConfigTable::Instance();
if (tab == (ConfigTable *)0L)
return Flag();
return tab->AmInitializing();
}
template<class GetConfig>
ConfigString Config<GetConfig>::Name(void)
{
return GetConfig::get_name();
}
template<class GetConfig>
bool Config<GetConfig>::Flag(void)
{
return GetConfig::_flag;
}
template<class GetConfig>
void Config<GetConfig>::Flag(bool f)
{
GetConfig::_flag = f;
}
template<class GetConfig>
void Config<GetConfig>::Init(void)
{
if (Flag())
return;
total_time_config_init -= clock();
Flag(true);
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 {
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<class GetConfig>
Config<GetConfig>::Config(void)
{
Init();
}
template<class GetConfig>
Config<GetConfig>::~Config(void)
{
}
template<class GetConfig>
bool Config<GetConfig>::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<class GetConfig>
ConfigString Config<GetConfig>::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<class GetConfig>
ConfigTable::Symbol& Config<GetConfig>::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<class GetConfig>
bool Config<GetConfig>::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<class GetConfig>
int Config<GetConfig>::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<class GetConfig>
float Config<GetConfig>::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<class GetConfig>
double Config<GetConfig>::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<class GetConfig>
ConfigString Config<GetConfig>::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<ConfigureGetConfig_ ## name>; \
extern expcl Config::Config<ConfigureGetConfig_ ## name> 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<ConfigureGetConfig_ ## name> 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<ConfigureGetConfig_ ## name> 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<ConfigureGetConfig_ ## name> 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<ConfigureGetConfig_ ## name> 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<ConfigureGetConfig_ ## name> 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__ */