321 lines
8.8 KiB
C++
321 lines
8.8 KiB
C++
// Filename: dconfig.h
|
|
// Created by: cary (14Jul98)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d-general@lists.sourceforge.net .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef DCONFIG_H
|
|
#define DCONFIG_H
|
|
|
|
#include "dtoolbase.h"
|
|
|
|
#include "config_setup.h"
|
|
#include "config_dconfig.h"
|
|
#include "configTable.h"
|
|
#include "executionEnvironment.h"
|
|
#include "configVariableString.h"
|
|
#include "configVariableBool.h"
|
|
#include "configVariableInt.h"
|
|
#include "configVariableDouble.h"
|
|
#include "configVariableList.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_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 GetConfig>
|
|
class Config {
|
|
public:
|
|
Config();
|
|
~Config();
|
|
static bool AmInitializing();
|
|
static ConfigString Name();
|
|
static bool Flag();
|
|
static void Init();
|
|
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 = "");
|
|
protected:
|
|
static void ConfigFunc();
|
|
static void Flag(bool);
|
|
};
|
|
|
|
// Implementation follows
|
|
|
|
template<class GetConfig>
|
|
void Config<GetConfig>::ConfigFunc() {
|
|
GetConfig::config_func();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
bool Config<GetConfig>::AmInitializing() {
|
|
return false;
|
|
}
|
|
|
|
template<class GetConfig>
|
|
ConfigString Config<GetConfig>::Name() {
|
|
return GetConfig::get_name();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
bool Config<GetConfig>::Flag() {
|
|
return GetConfig::_flag;
|
|
}
|
|
|
|
template<class GetConfig>
|
|
void Config<GetConfig>::Flag(bool f) {
|
|
GetConfig::_flag = f;
|
|
}
|
|
|
|
template<class GetConfig>
|
|
void Config<GetConfig>::Init() {
|
|
if (Flag())
|
|
return;
|
|
|
|
Flag(true);
|
|
|
|
ConfigFunc();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
Config<GetConfig>::Config() {
|
|
Init();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
Config<GetConfig>::~Config() {
|
|
}
|
|
|
|
template<class GetConfig>
|
|
bool Config<GetConfig>::Defined(const ConfigString& sym)
|
|
{
|
|
Init();
|
|
return true;
|
|
}
|
|
|
|
template<class GetConfig>
|
|
ConfigString Config<GetConfig>::Get(ConfigString sym)
|
|
{
|
|
Init();
|
|
ConfigVariableString var(sym);
|
|
return var.get_value();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
ConfigTable::Symbol& Config<GetConfig>::GetAll(const ConfigString sym,
|
|
ConfigTable::Symbol& s)
|
|
{
|
|
Init();
|
|
ConfigVariableList var(sym, 0, "DConfig");
|
|
|
|
int num_values = var.get_num_values();
|
|
for (int i = 0; i < num_values; i++) {
|
|
string value = var.get_string_value(i);
|
|
s.push_back(SymbolEnt(SymbolEnt::ConfigFile, value));
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
template<class GetConfig>
|
|
bool Config<GetConfig>::GetBool(const ConfigString sym, bool def)
|
|
{
|
|
Init();
|
|
ConfigVariableBool var(sym, def, 0, "DConfig");
|
|
return var.get_value();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
int Config<GetConfig>::GetInt(const ConfigString sym, int def)
|
|
{
|
|
Init();
|
|
ConfigVariableInt var(sym, def, 0, "DConfig");
|
|
return var.get_value();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
float Config<GetConfig>::GetFloat(const ConfigString sym, float def)
|
|
{
|
|
Init();
|
|
ConfigVariableDouble var(sym, def, 0, "DConfig");
|
|
return var.get_value();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
double Config<GetConfig>::GetDouble(const ConfigString sym, double def)
|
|
{
|
|
Init();
|
|
ConfigVariableDouble var(sym, def, 0, "DConfig");
|
|
return var.get_value();
|
|
}
|
|
|
|
template<class GetConfig>
|
|
ConfigString Config<GetConfig>::GetString(const ConfigString sym,
|
|
const ConfigString def)
|
|
{
|
|
Init();
|
|
ConfigVariableString var(sym, def, 0, "DConfig");
|
|
return var.get_value();
|
|
}
|
|
|
|
#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__ */
|