From fa32be5de472375aca6f7c59aa60da366fda061b Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 22 Oct 2004 23:13:49 +0000 Subject: [PATCH] refinements to prc system --- direct/src/showbase/ShowBase.py | 2 + dtool/src/dconfig/Sources.pp | 12 +- dtool/src/dconfig/configTable.I | 57 -- dtool/src/dconfig/configTable.cxx | 798 ------------------ dtool/src/dconfig/configTable.h | 71 -- dtool/src/dconfig/dconfig.h | 44 +- dtool/src/dconfig/test_serialization.cxx | 87 -- .../interrogatedb/config_interrogatedb.cxx | 15 +- .../src/interrogatedb/config_interrogatedb.h | 4 +- .../src/interrogatedb/interrogateDatabase.cxx | 2 +- .../interrogatedb/interrogate_interface.cxx | 10 +- .../src/interrogatedb/interrogate_interface.h | 1 + dtool/src/prc/Sources.pp | 8 + dtool/src/prc/configFlags.I | 18 + dtool/src/prc/configFlags.cxx | 54 ++ dtool/src/prc/configFlags.h | 62 ++ dtool/src/prc/configPage.cxx | 5 + dtool/src/prc/configPageManager.cxx | 12 +- dtool/src/prc/configVariable.I | 142 +--- dtool/src/prc/configVariable.cxx | 24 - dtool/src/prc/configVariable.h | 35 +- dtool/src/prc/configVariableBase.I | 207 +++++ dtool/src/prc/configVariableBase.cxx | 40 + dtool/src/prc/configVariableBase.h | 73 ++ dtool/src/prc/configVariableBool.I | 9 +- dtool/src/prc/configVariableBool.h | 5 +- dtool/src/prc/configVariableCore.I | 105 ++- dtool/src/prc/configVariableCore.cxx | 105 ++- dtool/src/prc/configVariableCore.h | 29 +- dtool/src/prc/configVariableDouble.I | 2 +- dtool/src/prc/configVariableDouble.cxx | 7 +- dtool/src/prc/configVariableDouble.h | 5 +- dtool/src/prc/configVariableEnum.I | 188 +++++ dtool/src/prc/configVariableEnum.cxx | 19 + dtool/src/prc/configVariableEnum.h | 79 ++ dtool/src/prc/configVariableInt.I | 2 +- dtool/src/prc/configVariableInt.cxx | 7 +- dtool/src/prc/configVariableInt.h | 5 +- dtool/src/prc/configVariableList.I | 90 -- dtool/src/prc/configVariableList.cxx | 16 +- dtool/src/prc/configVariableList.h | 28 +- dtool/src/prc/configVariableManager.cxx | 142 ++-- dtool/src/prc/configVariableManager.h | 4 +- dtool/src/prc/configVariableSearchPath.I | 214 +++++ dtool/src/prc/configVariableSearchPath.cxx | 74 ++ dtool/src/prc/configVariableSearchPath.h | 90 ++ dtool/src/prc/configVariableString.I | 24 +- dtool/src/prc/configVariableString.h | 7 +- dtool/src/prc/configVariableTempl.h | 41 - dtool/src/prc/notify.cxx | 3 +- dtool/src/prc/notify.h | 3 +- dtool/src/prc/notifyCategory.I | 12 +- dtool/src/prc/notifyCategory.cxx | 88 +- dtool/src/prc/notifyCategory.h | 12 +- dtool/src/prc/prcKeyRegistry.cxx | 12 +- dtool/src/prc/prcKeyRegistry.h | 2 +- dtool/src/pystub/pystub.cxx | 2 + .../src/test_interrogate/test_interrogate.cxx | 12 +- panda/src/express/config_express.N | 2 + panda/src/express/config_express.h | 2 + panda/src/pstatclient/pStatProperties.cxx | 61 +- panda/src/putil/Sources.pp | 6 +- panda/src/putil/putil_composite1.cxx | 1 + 63 files changed, 1563 insertions(+), 1735 deletions(-) delete mode 100644 dtool/src/dconfig/test_serialization.cxx create mode 100644 dtool/src/prc/configFlags.I create mode 100644 dtool/src/prc/configFlags.cxx create mode 100644 dtool/src/prc/configFlags.h create mode 100644 dtool/src/prc/configVariableBase.I create mode 100644 dtool/src/prc/configVariableBase.cxx create mode 100644 dtool/src/prc/configVariableBase.h create mode 100644 dtool/src/prc/configVariableEnum.I create mode 100644 dtool/src/prc/configVariableEnum.cxx create mode 100644 dtool/src/prc/configVariableEnum.h create mode 100644 dtool/src/prc/configVariableSearchPath.I create mode 100644 dtool/src/prc/configVariableSearchPath.cxx create mode 100644 dtool/src/prc/configVariableSearchPath.h delete mode 100644 dtool/src/prc/configVariableTempl.h diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index ebb76b1f9d..8bfcf12b85 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -262,6 +262,8 @@ class ShowBase(DirectObject.DirectObject): __builtins__["directNotify"] = directNotify __builtins__["globalClock"] = ClockObject.getGlobalClock() __builtins__["vfs"] = vfs + __builtins__["cpMgr"] = ConfigPageManager.getGlobalPtr() + __builtins__["cvMgr"] = ConfigVariableManager.getGlobalPtr() __builtins__["__dev__"] = base.config.GetBool('want-dev', 0) if __debug__: __builtins__["deltaProfiler"] = DeltaProfiler.DeltaProfiler("ShowBase") diff --git a/dtool/src/dconfig/Sources.pp b/dtool/src/dconfig/Sources.pp index c7bd9aee9b..871fcdc2ab 100644 --- a/dtool/src/dconfig/Sources.pp +++ b/dtool/src/dconfig/Sources.pp @@ -9,7 +9,7 @@ configTable.I configTable.h \ config_dconfig.h config_setup.h \ dconfig.I dconfig.h \ - serialization.I serialization.h \ + serialization.I serialization.h \ symbolEnt.I symbolEnt.h #define INCLUDED_SOURCES \ @@ -19,8 +19,8 @@ #define INSTALL_HEADERS \ configTable.I configTable.h config_dconfig.h config_setup.h \ dconfig.I dconfig.h \ - serialization.I serialization.h symbolEnt.I \ - symbolEnt.h + serialization.I serialization.h \ + symbolEnt.I symbolEnt.h #end lib_target @@ -47,9 +47,3 @@ #define SOURCES test_searchpath.cxx #define LOCAL_LIBS dconfig $[LOCAL_LIBS] #end test_bin_target - -#begin test_bin_target - #define TARGET test_serialization - #define SOURCES test_serialization.cxx - #define LOCAL_LIBS dconfig $[LOCAL_LIBS] -#end test_bin_target diff --git a/dtool/src/dconfig/configTable.I b/dtool/src/dconfig/configTable.I index 532823cf3d..cd92f4095e 100644 --- a/dtool/src/dconfig/configTable.I +++ b/dtool/src/dconfig/configTable.I @@ -15,60 +15,3 @@ // panda3d-general@lists.sourceforge.net . // //////////////////////////////////////////////////////////////////// - - -INLINE void ConfigTable::ConfigDbgDefault() { - // this should not be called if CONFIG_CONFIG=:configdbg=1 - configdbg = false; - microconfig_cat->set_severity(NS_info); - dconfig_cat->set_severity(NS_info); -} - -INLINE void ConfigTable::ConfigExeDefault() { - configexe = false; -} - -INLINE void ConfigTable::ReadArgsDefault() { - readargs = true; -} - -INLINE void ConfigTable::ReadEnvsDefault() { - readenvs = true; -} - -INLINE void ConfigTable::PathSepDefault() { - pathsep = ": "; -} - -INLINE void ConfigTable::FileSepDefault() { - filesep = "/"; -} - -INLINE void ConfigTable::ConfigNameDefault() { - configname.push_back(GlobPattern("Configrc")); - configname.push_back(GlobPattern("*.prc")); -} - -INLINE void ConfigTable::ConfigArgsDefault() { - configargs = ""; -} - -INLINE void ConfigTable::ConfigPathDefault() { - configpath = ""; -} - -INLINE void ConfigTable::ConfigCmtDefault() { - configcmt = "#"; -} - -INLINE void ConfigTable::ArgSuffixDefault() { - argsuffix = "_ARGS"; -} - -INLINE void ConfigTable::CommandStubDefault() { - commandstub = "CONFIG"; -} - -INLINE ConfigString ConfigTable::GetConfigPath() const { - return configpath; -} diff --git a/dtool/src/dconfig/configTable.cxx b/dtool/src/dconfig/configTable.cxx index 66576be493..17f6a88652 100644 --- a/dtool/src/dconfig/configTable.cxx +++ b/dtool/src/dconfig/configTable.cxx @@ -16,802 +16,4 @@ // //////////////////////////////////////////////////////////////////// -#include "dconfig.h" #include "configTable.h" -#include "dSearchPath.h" -#include "executionEnvironment.h" -#include "config_dconfig.h" -#include "pfstream.h" -#include "serialization.h" - -#ifdef PENV_PS2 - -#include -#include -#include - -#endif // PENV_PS2 - -//#define DISABLE_CONFIG - -using namespace Config; - -ConfigTable* ConfigTable::_instance = (ConfigTable*)0L; - -void ConfigTable::CropString(ConfigString& S) { - size_t i = S.find_first_not_of(" \t\r\f\n"); - if (i != ConfigString::npos) { - size_t j = S.find_last_not_of(" \t\r\f\n"); - if (j != ConfigString::npos) - S = S.substr(i, j-i+1); - else - S = S.substr(i, ConfigString::npos); - } else - S.erase(0, ConfigString::npos); -} - -void ConfigTable::DeComment(ConfigString& S) { - // If the comment delimiter appears in the line followed by - // whitespace, strip that part of the line out. - - size_t i = S.find(configcmt); - while (i != ConfigString::npos) { - if (i + configcmt.length() < S.length() && - isspace(S[i + configcmt.length()])) { - // Here's a comment. - S.erase(i, ConfigString::npos); - return; - } - - i = S.find(configcmt, i + 1); - } -} - -bool ConfigTable::IsComment(const ConfigString& S) { - // Returns true if the line begins with the comment delimiter, - // whether or not the delimiter is followed by whitespace. - return (S.substr(0, configcmt.length()) == configcmt); -} - -void ConfigTable::UpCase(ConfigString& S) { - for (ConfigString::iterator i=S.begin(); i!=S.end(); ++i) - (*i) = toupper(*i); -} - -ConfigString ConfigTable::NextWord(const ConfigString& S) { - int i(S.find_first_of(" \t\r\f\n")); - return S.substr(0, i); -} - -ConfigString ConfigTable::PopNextWord(ConfigString& S) { - int i(S.find_first_of(" \t\r\f\n")); - ConfigString ret(S.substr(0, i)); - S.erase(0, i); - CropString(S); - return ret; -} - -void ConfigTable::ParseConfigFile(istream& is, const ConfigString& Filename) { - ConfigString line; - - while (!is.eof() && !is.fail()) { - std::getline(is, line); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "read from " << Filename << ": '" << line - << "'" << endl; - DeComment(line); - CropString(line); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "cropped line to: '" << line << "'" - << endl; - if (!IsComment(line)) { - ConfigString protosym(PopNextWord(line)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "protosym is '" << protosym - << "' with value of '" << line << "'" - << endl; - size_t i(protosym.find(".")); - if (i == ConfigString::npos) { - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "this is an unqualified symbol" - << endl; - unqualified[protosym].push_back(SymEnt(SymEnt::ConfigFile, line, Filename)); - } else { - ConfigString scope(protosym.substr(0, i)); - ConfigString sym(protosym.substr(i+1, ConfigString::npos)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "this is a qualified symbol." - << " scope '" << scope - << "', symbol '" << sym << "'" << endl; - (qualified[scope])[sym].push_back(SymEnt(SymEnt::ConfigFile, line, Filename)); - } - } else if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "line is detected as a comment" << endl; - } -} - -void ConfigTable::ReadConfigFile() { - // The configpath variable lists the environment variables that - // themselves should be considered to contain search paths for - // Configrc files. This is one level of indirection from the - // intuitive definition. - - DSearchPath config_search; - - // The configdir variable gets priority--it names a directory that - // ends up first on the search path. - if (!configdir.empty()) { - config_search.append_directory(Filename::from_os_specific(configdir)); - } - - // Then all of the directories named (indirectly) by configpath. - // This variable actually names a space-delimited list of - // environment variable names, each of which contains a space- or - // colon-delimited search path. - while (!configpath.empty()) { - int i = configpath.find_first_of(" "); - ConfigString stmp = configpath.substr(0, i); - if (ExecutionEnvironment::has_environment_variable(stmp)) { - string path = ExecutionEnvironment::get_environment_variable(stmp); - - size_t p = 0; - while (p < path.length()) { - size_t q = path.find_first_of(pathsep, p); - if (q == string::npos) { - config_search.append_directory(Filename::from_os_specific(path.substr(p))); - break; - } - if (q != p) { - config_search.append_directory(Filename::from_os_specific(path.substr(p, q - p))); - } - p = q + 1; - } - } - configpath.erase(0, i); - CropString(configpath); - } - - if (microconfig_cat->is_spam()) { - microconfig_cat->spam() - << "search path from configdir and configpath is: " - << config_search << endl; - } - - DSearchPath::Results config_files; - - if (microconfig_cat->is_spam()) { - microconfig_cat->spam() << "searching for files matching:\n"; - for (Globs::const_iterator gi = configname.begin(); - gi != configname.end(); - ++gi) { - microconfig_cat->spam() << " " << (*gi) << endl; - } - } - - for (int di = 0; di < config_search.get_num_directories(); di++) { - const Filename &directory = config_search.get_directory(di); - if (directory.is_directory()) { - vector_string files; - directory.scan_directory(files); - // Scan the files into reverse alphabetical order, to re-invert - // the native Config sorting, so that the alphabetically last - // file has precedence. - for (vector_string::reverse_iterator fi = files.rbegin(); - fi != files.rend(); - ++fi) { - bool matches = false; - for (Globs::const_iterator gi = configname.begin(); - gi != configname.end() && !matches; - ++gi) { - matches = (*gi).matches(*fi); - } - if (matches) { - Filename file(directory, (*fi)); - config_files.add_file(file); - } - } - } - } - - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "found " << config_files.get_num_files() - << " files" << endl; - - int num_config_files = config_files.get_num_files(); - for (int i = num_config_files - 1; i >= 0; i--) { - Filename config_file = config_files.get_file(i); - - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "examining file '" << config_file << "'" - << endl; - - if (!config_file.is_regular_file()) { - if (microconfig_cat->is_spam()) { - microconfig_cat->spam() - << "file is not a regular file, ignoring.\n"; - } - - } else if (configexe && config_file.is_executable()) { - ConfigString line = config_file.to_os_specific() + " " + configargs; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "file is executable, running '" - << line << "'" << endl; - IPipeStream ifs(line); - ParseConfigFile(ifs, config_file); - } else { - #if 0 - microconfig_cat->info() << "Reading .prc file '" << config_file << "'"<< endl; - #endif - - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "file is not executable, reading normally" << endl; - -#ifdef PENV_PS2 - ConfigString line = PS2_FILE_PREFIX + convert_pathname(config_file); - - int fd = sceOpen((char *) line.c_str(), SCE_RDONLY); - char line_buffer[2048]; - - memset(line_buffer, 0, 2048); - - ConfigString file_buffer; - - while (sceRead(fd, line_buffer, 2048) > 0) - { - file_buffer += line_buffer; - memset(line_buffer, 0, 2048); - } - - sceClose(fd); - - istrstream ifs(file_buffer.c_str()); -#else - ifstream ifs(config_file.to_os_specific().c_str()); -#endif - ParseConfigFile(ifs, config_file); - } - } -} - -void ConfigTable::ParseCommandEnv(ConfigString& S, const ConfigString& sym) -{ - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "value of '" << sym << "' is '" << S << "'" - << endl; - while (!S.empty()) { - ConfigString protosym(PopNextWord(S)); - bool ok = false; - bool state = false; - if (protosym[0] == '-') - ok = true; - else if (protosym[0] == '+') { - ok = true; - state = true; - } - if (ok) { - protosym.erase(0, 1); - CropString(protosym); - size_t i(protosym.find(".")); - if (i == ConfigString::npos) { - unqualified[protosym].push_back(SymEnt(SymEnt::CommandEnv, - NextWord(S), sym, state)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "unqualified symbol '" << protosym - << "' with value '" << NextWord(S) - << "'" << endl; - } else { - ConfigString scope(protosym.substr(0, i)); - ConfigString sym(protosym.substr(i+1, ConfigString::npos)); - (qualified[scope])[sym].push_back(SymEnt(SymEnt::CommandEnv, - NextWord(S), sym, state)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "qualified symbol '" << sym - << "' in scope '" << scope - << "' and value '" << NextWord(S) - << "'" << endl; - } - } else if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "'" << protosym - << "' was not recognized as an option" - << endl; - } -} - -void ConfigTable::ParseArgs() { - int n = 0; - int num_args = ExecutionEnvironment::get_num_args(); - - while ( n < num_args) { - bool ok = false; - bool state = false; - ConfigString line(ExecutionEnvironment::get_arg(n)); - CropString(line); - if (line[0] == '-') - ok = true; - else if (line[0] == '+') { - ok = true; - state = true; - } - if (ok) { - line.erase(0, 1); - CropString(line); - size_t i(line.find(".")); - ConfigString aparam; - if (n + 1 < num_args) { - aparam = ExecutionEnvironment::get_arg(n + 1); - } - - if (i == ConfigString::npos) { - unqualified[line].push_back(SymEnt(SymEnt::Commandline, - aparam, "", state)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "unqualified symbol '" << line - << "' with value '" << aparam - << "'" << endl; - } else { - ConfigString scope(line.substr(0, i)); - ConfigString sym(line.substr(i+1, ConfigString::npos)); - (qualified[scope])[sym].push_back(SymEnt(SymEnt::Commandline, - aparam, "", state)); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "qualified symbol '" << sym - << "' with scope '" << scope - << "' and value '" << aparam - << "'" << endl; - } - } else if (microconfig_cat->is_spam()) { - microconfig_cat->spam() << "argument #" << n << " ('" << line - << "') is not recognized as an option" - << endl; - } - ++n; - } -} - -void ConfigTable::ConfigDirDefault() { - // The configdir default comes from $PRC_DIR, or from the - // compiled in DEFAULT_PRC_DIR if that's unspecified. - configdir = ExecutionEnvironment::get_environment_variable("PRC_DIR"); - if (configdir.empty()) { - configdir = DEFAULT_PRC_DIR; - } -} - -void ConfigTable::MicroConfig() { -/* -#ifndef NDEBUG - NotifySeverity mcs = microconfig_cat->get_severity(); - microconfig_cat->set_severity(NS_spam); - - NotifySeverity cs = config_cat->get_severity(); - config_cat->set_severity(NS_spam); -#else * NDEBUG * -*/ - // NotifySeverity mcs = microconfig_cat->get_severity(); - microconfig_cat->set_severity(NS_info); - - // NotifySeverity cs = dconfig_cat->get_severity(); - dconfig_cat->set_severity(NS_info); -/* -#endif * NDEBUG * -*/ - string cc = ExecutionEnvironment::get_environment_variable("CONFIG_CONFIG"); - if (microconfig_cat->is_spam()) { - microconfig_cat->spam() << "CONFIG_CONFIG = '" << cc << "'" << endl; - } - bool cdbg = false; - bool cexe = false; - bool psep = false; - bool fsep = false; - bool cname = false; - bool cargs = false; - bool cpath = false; - bool cdir = false; - bool ccmt = false; - bool asuff = false; - bool cstub = false; - bool rdarg = false; - bool rdenv = false; - if (!cc.empty()) { - ConfigString configconfig(cc); - if (configconfig.length() > 1) { - ConfigString assign = "="; - ConfigString sep = configconfig.substr(0, 1); - if (microconfig_cat->is_spam()) { - microconfig_cat->spam() << "separator character is: '" << sep - << "'" << endl; - } - typedef std::vector strvec; - strvec sv; - size_t q = 1; - size_t p = configconfig.find(sep, q); - while (p != ConfigString::npos) { - sv.push_back(configconfig.substr(q, p - q)); - q = p + 1; - p = configconfig.find(sep, q); - } - if (q + 1 < configconfig.size()) { - sv.push_back(configconfig.substr(q)); - } - - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "extracted vector of microconfig options" << endl; - for (strvec::iterator i=sv.begin(); i!=sv.end(); ++i) { - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "parsing microconfig option '" - << *i << "'" << endl; - if ((*i).length() == 1) { - // new assignment character - assign += *i; - continue; - } - size_t j = (*i).find_first_of(assign); - if (j != ConfigString::npos) { - ConfigString tok = (*i).substr(0, j); - ConfigString rest = (*i).substr(j+1, ConfigString::npos); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "split microconfig option into '" - << tok << "' and '" << rest << "'" - << endl; - if (tok == "pathsep") { - pathsep = rest; - psep = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig pathsep directive, " - << "setting the path separator to '" << pathsep << "'" - << endl; - } else if (tok == "filesep") { - filesep = rest; - fsep = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig filesep directive, " - << "setting the file separator to '" << filesep << "'" - << endl; - } else if (tok == "configname") { - configname.push_back(GlobPattern(rest)); - cname = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configname directive, " - << "adding configname '" << rest << "'" << endl; - } else if (tok == "configargs") { - configargs = rest; - cargs = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configargs directive, " - << "setting the config file args to '" - << configargs << "'" - << endl; - } else if (tok == "configpath") { - if (cpath) { - configpath += " " + rest; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configpath directive, " - << "adding '" << rest << "' to the configpath (now '" - << configpath << "')" - << endl; - } else { - configpath = rest; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configpath directive, " - << "setting the configpath to '" << configpath << "'" - << endl; - } - cpath = true; - } else if (tok == "configdir") { - configdir = rest; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configdir directive, " - << "setting the configdir to '" << configdir << "'" - << endl; - cdir = true; - } else if (tok == "configcmt") { - configcmt = rest; - ccmt = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configcmt directive, " - << "setting the config comment to '" << configcmt - << "'" << endl; - } else if (tok == "argsuffix") { - argsuffix = rest; - asuff = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig argsuffix directive, " - << "setting the argument environment suffix to '" - << argsuffix << "'" << endl; - } else if (tok == "commandstub") { - commandstub = rest; - cstub = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig commandstub directive, " - << "setting the command environment stub " - << "to '" << commandstub << "'" << endl; - } else if (tok == "configdbg") { - configdbg = TrueOrFalse(rest); - cdbg = true; - if (configdbg) { - microconfig_cat->set_severity(NS_spam); - dconfig_cat->set_severity(NS_spam); - } else { - microconfig_cat->set_severity(NS_info); - dconfig_cat->set_severity(NS_info); - } - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configdbg directive, " - << "setting the config spam state to " << configdbg - << endl; - } else if (tok == "configexe") { - configexe = TrueOrFalse(rest); - cexe = true; - if (configexe) { - microconfig_cat->set_severity(NS_spam); - dconfig_cat->set_severity(NS_spam); - } else { - microconfig_cat->set_severity(NS_info); - dconfig_cat->set_severity(NS_info); - } - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig configexe directive, " - << "setting the config spam state to " << configexe - << endl; - } else if (tok == "readargs") { - readargs = TrueOrFalse(rest); - rdarg = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig readargs directive, " - << (readargs?"will":"will not") - << " read from the commandline." << endl; - } else if (tok == "readenv") { - readenvs = TrueOrFalse(rest); - rdenv = true; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "got a microconfig readenv directive, " - << (readargs?"will":"will not") - << " read the environment." << endl; - } - } else if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "no '=' in microconfig option, ignoring it" << endl; - } - } else if (microconfig_cat->is_spam()) - microconfig_cat->spam() - << "CONFIG_CONFIG contains only a single character" << endl; - } else if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "CONFIG_CONFIG is empty" << endl; - if (!cdbg) - ConfigDbgDefault(); - if (!cexe) - ConfigExeDefault(); - if (!psep) { - PathSepDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for pathsep, " - << "setting to default '" << pathsep << "'" - << endl; - } - if (!fsep) { - FileSepDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for filesep, " - << "setting to default '" << filesep << "'" - << endl; - } - if (!cname) { - ConfigNameDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for configname, " - << "setting to default" << endl; - } - if (!cargs) { - ConfigArgsDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for configargs, " - << "setting to default '" << configargs - << "'" << endl; - } - if (!cpath) { - ConfigPathDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for configpath, " - << "setting to default '" << configpath - << "'" << endl; - } - if (!cdir) { - ConfigDirDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for configdir, " - << "setting to default '" << configdir - << "'" << endl; - } - if (!ccmt) { - ConfigCmtDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for configcmt, " - << "setting to default '" << configcmt - << "'" << endl; - } - if (!asuff) { - ArgSuffixDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for argsuffix, " - << "setting to default '" << argsuffix - << "'" << endl; - } - if (!cstub) { - CommandStubDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for commandstub, " - << "setting to default '" << commandstub - << "'" << endl; - } - if (!rdarg) { - ReadArgsDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for readargs, " - << "setting to default: " - << (readargs?"true":"false") << endl; - } - if (!rdenv) { - ReadEnvsDefault(); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "no microconfig for readenv, " - << "setting to default: " - << (readargs?"true":"false") << endl; - } -} - -void ConfigTable::GetData() { - MicroConfig(); -#ifndef DISABLE_CONFIG - ReadConfigFile(); - if (readenvs) { - ConfigString comarg = commandstub + argsuffix; - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "comarg is '" << comarg << "'" - << endl; - if (ExecutionEnvironment::has_environment_variable(comarg)) { - ConfigString env = ExecutionEnvironment::get_environment_variable(comarg); - ParseCommandEnv(env, comarg); - } - ConfigString line = ExecutionEnvironment::get_binary_name() + argsuffix; - UpCase(line); - if (microconfig_cat->is_spam()) - microconfig_cat->spam() << "binarg is '" << line << "'" - << endl; - if (ExecutionEnvironment::has_environment_variable(line)) { - ConfigString env = ExecutionEnvironment::get_environment_variable(line); - ParseCommandEnv(env, line); - } - } - if (readargs) - ParseArgs(); -#endif // DISABLE_CONFIG -} - -ConfigTable* ConfigTable::Instance() { - if (_instance == (ConfigTable*)0L) { - _instance = new ConfigTable; - _instance->GetData(); - _instance->_initializing = false; - } - return _instance; -} - -bool ConfigTable::AmInitializing() { - return _initializing; -} - -bool ConfigTable::TrueOrFalse(const ConfigString& in, bool def) { - bool ret = def; - ConfigString S = in; - UpCase(S); - if (S[0] == '#') { - if (S[1] == 'F') { - ret = false; - } else if (S[1] == 'T') { - ret = true; - } - } else if (S == "0") { - ret = false; - } else if (S == "1") { - ret = true; - } else if (S == "FALSE") { - ret = false; - } else if (S == "TRUE") { - ret = true; - } - return ret; -} - -bool ConfigTable::Defined(const ConfigString& sym, - const ConfigString qual) { -#ifdef DISABLE_CONFIG - return false; -#else - if (qual.empty()) { - return (unqualified.count(sym) != 0 || - ExecutionEnvironment::has_environment_variable(sym)); - - } else { - TableMap::const_iterator ti; - ti = qualified.find(qual); - if (ti != qualified.end()) { - const SymbolTable &table = (*ti).second; - if (table.count(sym) != 0) { - return true; - } - } - - return ExecutionEnvironment::has_environment_variable(qual + "." + sym); - } -#endif // DISABLE_CONFIG -} - -ConfigTable::SymEnt ConfigTable::Get(const ConfigString& sym, - const ConfigString qual) { -#ifndef DISABLE_CONFIG - const ConfigTable::Symbol &symbol = GetSym(sym, qual); - if (!symbol.empty()) { - return symbol.back(); - } - - // No explicit config definition; fall back to the environment. - string envvar = sym; - if (!qual.empty()) { - envvar = qual + "." + sym; - } - - if (ExecutionEnvironment::has_environment_variable(sym)) { - string def = ExecutionEnvironment::get_environment_variable(sym); - return ConfigTable::SymEnt(ConfigTable::SymEnt::Environment, def); - } -#endif // DISABLE_CONFIG - - // No definition for the variable. Too bad for you. - return ConfigTable::SymEnt(); -} - -const ConfigTable::Symbol& ConfigTable::GetSym(const ConfigString& sym, - const ConfigString qual) { - static ConfigTable::Symbol empty_symbol; - -#ifndef DISABLE_CONFIG - total_num_get++; - if (qual.empty()) { - SymbolTable::const_iterator si; - si = unqualified.find(sym); - if (si != unqualified.end()) { - return (*si).second; - } - - } else { - TableMap::const_iterator ti; - ti = qualified.find(qual); - if (ti != qualified.end()) { - const SymbolTable &table = (*ti).second; - SymbolTable::const_iterator si; - si = table.find(sym); - if (si != table.end()) { - return (*si).second; - } - } - } -#endif // DISABLE_CONFIG - - return empty_symbol; -} diff --git a/dtool/src/dconfig/configTable.h b/dtool/src/dconfig/configTable.h index 99ad3e027c..ff8fbf14b4 100644 --- a/dtool/src/dconfig/configTable.h +++ b/dtool/src/dconfig/configTable.h @@ -21,85 +21,14 @@ #include "dtoolbase.h" -#include "config_setup.h" -#include "config_dconfig.h" #include "symbolEnt.h" -#include "globPattern.h" - -#include "pvector.h" -#include "pmap.h" namespace Config { class EXPCL_DTOOLCONFIG ConfigTable { -private: - static ConfigTable* _instance; - public: typedef SymbolEnt SymEnt; typedef vector_SymbolEnt Symbol; - -private: - typedef phash_map > SymbolTable; - typedef phash_map > TableMap; - typedef pvector Globs; - - SymbolTable unqualified; - TableMap qualified; - bool _initializing; - bool configexe; - bool configdbg; - bool readargs; - bool readenvs; - ConfigString pathsep; - ConfigString filesep; - Globs configname; - ConfigString configargs; - ConfigString configpath; - ConfigString configdir; - ConfigString configcmt; - ConfigString argsuffix; - ConfigString commandstub; - - static void CropString(ConfigString& S); - void DeComment(ConfigString& S); - bool IsComment(const ConfigString&); - static void UpCase(ConfigString&); - ConfigString NextWord(const ConfigString& S); - ConfigString PopNextWord(ConfigString& S); - void ParseConfigFile(istream&, const ConfigString&); - void ReadConfigFile(); - void ParseCommandEnv(ConfigString&, const ConfigString&); - void ParseArgs(); - INLINE void ConfigDbgDefault(); - INLINE void ConfigExeDefault(); - INLINE void ReadArgsDefault(); - INLINE void ReadEnvsDefault(); - INLINE void PathSepDefault(); - INLINE void FileSepDefault(); - INLINE void ConfigNameDefault(); - INLINE void ConfigArgsDefault(); - INLINE void ConfigPathDefault(); - void ConfigDirDefault(); - INLINE void ConfigCmtDefault(); - INLINE void ArgSuffixDefault(); - INLINE void CommandStubDefault(); - void MicroConfig(); - void GetData(); - -protected: - ConfigTable() : _initializing(true) {} - -public: - static ConfigTable* Instance(); - bool AmInitializing(); - static bool TrueOrFalse(const ConfigString& in, bool def = false); - bool Defined(const ConfigString& sym, const ConfigString qual=""); - SymEnt Get(const ConfigString& sym, const ConfigString qual = ""); - const Symbol& GetSym(const ConfigString& sym, - const ConfigString qual = ""); - INLINE ConfigString GetConfigPath() const; - INLINE bool IsConfigDbg() { return configdbg; }; }; #include "configTable.I" diff --git a/dtool/src/dconfig/dconfig.h b/dtool/src/dconfig/dconfig.h index 8c1ba07e48..1c34823f11 100644 --- a/dtool/src/dconfig/dconfig.h +++ b/dtool/src/dconfig/dconfig.h @@ -100,10 +100,7 @@ void Config::ConfigFunc() { template bool Config::AmInitializing() { - ConfigTable* tab = ConfigTable::Instance(); - if (tab == (ConfigTable *)0L) - return Flag(); - return tab->AmInitializing(); + return false; } template @@ -125,38 +122,10 @@ template void Config::Init() { 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 @@ -172,14 +141,7 @@ 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; + return true; } template diff --git a/dtool/src/dconfig/test_serialization.cxx b/dtool/src/dconfig/test_serialization.cxx deleted file mode 100644 index 28cb2a8635..0000000000 --- a/dtool/src/dconfig/test_serialization.cxx +++ /dev/null @@ -1,87 +0,0 @@ -// Filename: test_serialization.cxx -// Created by: cary (31Aug98) -// -//////////////////////////////////////////////////////////////////// -// -// 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 . -// -//////////////////////////////////////////////////////////////////// - -#include "serialization.h" -#include -#include -#include -#include - -typedef std::list intlist; -typedef std::vector floatvec; - -intlist refints; -floatvec reffloats; - -int ints[10] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3 }; -float floats[10] = { 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0 }; - -void TestToString() -{ - std::string line; - Serialize::Serializer intser(refints); - Serialize::Serializer floatser(reffloats); - - line = intser; - cout << "Int list serialization: '" << line << "'" << endl; - line = floatser; - cout << "Float vector serialization: '" << line << "'" << endl; -} - -void TestFromString() -{ - std::string line; - Serialize::Serializer intser(refints); - Serialize::Serializer floatser(reffloats); - - line = intser; - Serialize::Deserializer intdes1(line); - cout << "Int list deserialization: "; - intlist ides1 = intdes1; - for (intlist::iterator i=ides1.begin(); i!=ides1.end(); ++i) { - if (i != ides1.begin()) - cout << ", "; - cout << (*i); - } - cout << endl; - line = floatser; - Serialize::Deserializer floatdes1(line); - cout << "Float vector deserialization: "; - floatvec fdes1 = floatdes1; - for (floatvec::iterator j=fdes1.begin(); j!=fdes1.end(); ++j) { - if (j != fdes1.begin()) - cout << ", "; - cout << (*j); - } - cout << endl; -} - -main() -{ - // initialize the collections - for (int i=0; i<10; ++i) { - refints.push_back(ints[i]); - reffloats.push_back(floats[i]); - } - - // now run tests - cout << "Serialization to string:" << endl; - TestToString(); - cout << endl << "Deserialization from string:" << endl; - TestFromString(); -} diff --git a/dtool/src/interrogatedb/config_interrogatedb.cxx b/dtool/src/interrogatedb/config_interrogatedb.cxx index b2cd5179ff..87024f50b2 100644 --- a/dtool/src/interrogatedb/config_interrogatedb.cxx +++ b/dtool/src/interrogatedb/config_interrogatedb.cxx @@ -18,7 +18,7 @@ #include "config_interrogatedb.h" #include "interrogate_request.h" - +#include "configVariableString.h" #include "dconfig.h" #if defined(WIN32_VC) && defined(_DEBUG) @@ -69,14 +69,7 @@ ConfigureFn(config_interrogatedb) { #endif } -DSearchPath & -get_interrogatedb_path() { - static DSearchPath *interrogatedb_path = NULL; - if (interrogatedb_path == (DSearchPath *)NULL) { - interrogatedb_path = new DSearchPath("."); - interrogatedb_path->append_path - (config_interrogatedb.GetString("ETC_PATH", ".")); - } - return *interrogatedb_path; -} +ConfigVariableSearchPath interrogatedb_path +("interrogatedb-path", 0, + "The search path for interrogate's *.in files."); diff --git a/dtool/src/interrogatedb/config_interrogatedb.h b/dtool/src/interrogatedb/config_interrogatedb.h index c1b5a22145..02db51090e 100644 --- a/dtool/src/interrogatedb/config_interrogatedb.h +++ b/dtool/src/interrogatedb/config_interrogatedb.h @@ -21,10 +21,10 @@ #include "dtoolbase.h" #include "notifyCategoryProxy.h" -#include "dSearchPath.h" +#include "configVariableSearchPath.h" NotifyCategoryDecl(interrogatedb, EXPCL_DTOOLCONFIG, EXPTP_DTOOLCONFIG); -DSearchPath &get_interrogatedb_path(); +extern ConfigVariableSearchPath interrogatedb_path; #endif diff --git a/dtool/src/interrogatedb/interrogateDatabase.cxx b/dtool/src/interrogatedb/interrogateDatabase.cxx index b1b28ec507..15fec971d3 100644 --- a/dtool/src/interrogatedb/interrogateDatabase.cxx +++ b/dtool/src/interrogatedb/interrogateDatabase.cxx @@ -892,7 +892,7 @@ read(istream &in, InterrogateModuleDef *def) { //////////////////////////////////////////////////////////////////// void InterrogateDatabase:: load_latest() { - const DSearchPath &searchpath = get_interrogatedb_path(); + const DSearchPath &searchpath = interrogatedb_path; Requests copy_requests; copy_requests.swap(_requests); diff --git a/dtool/src/interrogatedb/interrogate_interface.cxx b/dtool/src/interrogatedb/interrogate_interface.cxx index 5def12dbe5..7b2c3f17da 100644 --- a/dtool/src/interrogatedb/interrogate_interface.cxx +++ b/dtool/src/interrogatedb/interrogate_interface.cxx @@ -27,7 +27,15 @@ // passed in by the code generator. void interrogate_add_search_directory(const char *dirname) { - get_interrogatedb_path().append_directory(Filename::from_os_specific(dirname)); + interrogatedb_path.append_directory(Filename::from_os_specific(dirname)); +} + +// This function works similar to the above, but adds a complete path +// string--a list of multiple directories, separated by the standard +// delimiter--to the search path. +void +interrogate_add_search_path(const char *pathstring) { + interrogatedb_path.append_path(pathstring); } bool interrogate_error_flag() { diff --git a/dtool/src/interrogatedb/interrogate_interface.h b/dtool/src/interrogatedb/interrogate_interface.h index d733d5d054..8bd78d977d 100644 --- a/dtool/src/interrogatedb/interrogate_interface.h +++ b/dtool/src/interrogatedb/interrogate_interface.h @@ -91,6 +91,7 @@ enum AtomicToken { }; EXPCL_DTOOLCONFIG void interrogate_add_search_directory(const char *dirname); +EXPCL_DTOOLCONFIG void interrogate_add_search_path(const char *pathstring); EXPCL_DTOOLCONFIG bool interrogate_error_flag(); ////////////////////////////////////////////////////////////////////////// diff --git a/dtool/src/prc/Sources.pp b/dtool/src/prc/Sources.pp index 8b9e92becc..c5d98b256e 100644 --- a/dtool/src/prc/Sources.pp +++ b/dtool/src/prc/Sources.pp @@ -7,15 +7,19 @@ #define SOURCES \ config_prc.cxx config_prc.h \ configDeclaration.cxx configDeclaration.I configDeclaration.h \ + configFlags.cxx configFlags.I configFlags.h \ configPage.cxx configPage.I configPage.h \ configPageManager.cxx configPageManager.I configPageManager.h \ configVariable.cxx configVariable.I configVariable.h \ + configVariableBase.cxx configVariableBase.I configVariableBase.h \ configVariableBool.cxx configVariableBool.I configVariableBool.h \ configVariableCore.cxx configVariableCore.I configVariableCore.h \ configVariableDouble.cxx configVariableDouble.I configVariableDouble.h \ + configVariableEnum.cxx configVariableEnum.I configVariableEnum.h \ configVariableInt.cxx configVariableInt.I configVariableInt.h \ configVariableList.cxx configVariableList.I configVariableList.h \ configVariableManager.cxx configVariableManager.I configVariableManager.h \ + configVariableSearchPath.cxx configVariableSearchPath.I configVariableSearchPath.h \ configVariableString.cxx configVariableString.I configVariableString.h \ globPattern.cxx globPattern.I globPattern.h \ notify.cxx notify.I notify.h \ @@ -27,15 +31,19 @@ #define INSTALL_HEADERS \ config_prc.h \ configDeclaration.I configDeclaration.h \ + configFlags.I configFlags.h \ configPage.I configPage.h \ configPageManager.I configPageManager.h \ configVariable.I configVariable.h \ + configVariableBase.I configVariableBase.h \ configVariableBool.I configVariableBool.h \ configVariableCore.I configVariableCore.h \ configVariableDouble.I configVariableDouble.h \ + configVariableEnum.I configVariableEnum.h \ configVariableInt.I configVariableInt.h \ configVariableList.I configVariableList.h \ configVariableManager.I configVariableManager.h \ + configVariableSearchPath.I configVariableSearchPath.h \ configVariableString.I configVariableString.h \ globPattern.I globPattern.h \ notify.I notify.h \ diff --git a/dtool/src/prc/configFlags.I b/dtool/src/prc/configFlags.I new file mode 100644 index 0000000000..7791375f48 --- /dev/null +++ b/dtool/src/prc/configFlags.I @@ -0,0 +1,18 @@ +// Filename: configFlags.I +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + diff --git a/dtool/src/prc/configFlags.cxx b/dtool/src/prc/configFlags.cxx new file mode 100644 index 0000000000..9660a9fcc1 --- /dev/null +++ b/dtool/src/prc/configFlags.cxx @@ -0,0 +1,54 @@ +// Filename: configFlags.cxx +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#include "configFlags.h" + +//////////////////////////////////////////////////////////////////// +// Function: ConfigFlags::Type output operator +// Description: +//////////////////////////////////////////////////////////////////// +ostream & +operator << (ostream &out, ConfigFlags::ValueType type) { + switch (type) { + case ConfigFlags::VT_undefined: + return out << "undefined"; + + case ConfigFlags::VT_list: + return out << "list"; + + case ConfigFlags::VT_string: + return out << "string"; + + case ConfigFlags::VT_bool: + return out << "bool"; + + case ConfigFlags::VT_int: + return out << "int"; + + case ConfigFlags::VT_double: + return out << "double"; + + case ConfigFlags::VT_enum: + return out << "enum"; + + case ConfigFlags::VT_search_path: + return out << "search-path"; + } + + return out << "**invalid(" << (int)type << ")**"; +} diff --git a/dtool/src/prc/configFlags.h b/dtool/src/prc/configFlags.h new file mode 100644 index 0000000000..c8202f8ebc --- /dev/null +++ b/dtool/src/prc/configFlags.h @@ -0,0 +1,62 @@ +// Filename: configFlags.h +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 CONFIGFLAGS_H +#define CONFIGFLAGS_H + +#include "dtoolbase.h" + +//////////////////////////////////////////////////////////////////// +// Class : ConfigFlags +// Description : This class is the base class of both ConfigVariable +// and ConfigVariableCore. It exists only to provide a +// convenient name scoping for some enumerated values +// common to both classes. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOLCONFIG ConfigFlags { +PUBLISHED: + enum ValueType { + VT_undefined, + VT_list, + VT_string, + VT_bool, + VT_int, + VT_double, + VT_enum, + VT_search_path, + }; + + enum VariableFlags { + // Trust level. We have the bottom twelve bits reserved for a + // trust level indicator; then the open and closed bits are a + // special case. + F_trust_level_mask = 0x00000fff, + F_open = 0x00001000, + F_closed = 0x00002000, + + // F_dynamic means that the variable name is generated dynamically + // (possibly from a very large pool) and should not be included in + // the normal list of variable names. + F_dynamic = 0x00004000, + }; +}; + +ostream &operator << (ostream &out, ConfigFlags::ValueType type); + +#endif + diff --git a/dtool/src/prc/configPage.cxx b/dtool/src/prc/configPage.cxx index 18c812e1d1..e0c1668d65 100644 --- a/dtool/src/prc/configPage.cxx +++ b/dtool/src/prc/configPage.cxx @@ -116,6 +116,11 @@ clear() { // returned by the indicated istream, into the current // page file. Returns true on success, or false on some // I/O error. +// +// This is a low-level interface. Normally you do not +// need to call it directly. See the global functions +// load_prc_file() and unload_prc_file(), defined in +// panda/src/putil, for a higher-level interface. //////////////////////////////////////////////////////////////////// bool ConfigPage:: read_prc(istream &in) { diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx index 837e30d767..8a1a244250 100644 --- a/dtool/src/prc/configPageManager.cxx +++ b/dtool/src/prc/configPageManager.cxx @@ -245,8 +245,16 @@ reload_implicit_pages() { if ((file._file_flags & FF_execute) != 0 && filename.is_executable()) { // Attempt to execute the file as a command. - string args = ExecutionEnvironment::get_environment_variable(PRC_EXECUTABLE_ARGS_ENVVAR); - string command = filename.to_os_specific() + " " + args; + string command = filename.to_os_specific(); + + string envvar = PRC_EXECUTABLE_ARGS_ENVVAR; + if (!envvar.empty()) { + string args = ExecutionEnvironment::get_environment_variable(envvar); + if (!args.empty()) { + command += " "; + command += args; + } + } IPipeStream ifs(command); ConfigPage *page = new ConfigPage(filename, true, i); diff --git a/dtool/src/prc/configVariable.I b/dtool/src/prc/configVariable.I index b066ac3fd0..f6ee7b6489 100644 --- a/dtool/src/prc/configVariable.I +++ b/dtool/src/prc/configVariable.I @@ -24,20 +24,35 @@ // specialized ConfigVariableFoo derived class. //////////////////////////////////////////////////////////////////// INLINE ConfigVariable:: -ConfigVariable(const string &name, ConfigVariableCore::ValueType value_type) : - _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) +ConfigVariable(const string &name, ConfigVariable::ValueType value_type) : + ConfigVariableBase(name, value_type) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariable::Constructor +// Access: Protected +// Description: This constructor is only intended to be called from a +// specialized ConfigVariableFoo derived class. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariable:: +ConfigVariable(const string &name, ConfigVariable::ValueType value_type, + int flags, const string &description) : + ConfigVariableBase(name, value_type, flags, description) { - _core->set_value_type(value_type); } //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::Constructor // Access: Published -// Description: +// Description: Use this constructor to make a ConfigVariable of an +// unspecified type. Usually you'd want to do this just +// to reference a previously-defined ConfigVariable of a +// specific type, without having to know what type it is. //////////////////////////////////////////////////////////////////// INLINE ConfigVariable:: ConfigVariable(const string &name) : - _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) + ConfigVariableBase(name, VT_undefined) { _core->set_used(); } @@ -51,70 +66,6 @@ INLINE ConfigVariable:: ~ConfigVariable() { } -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::get_name -// Access: Published -// Description: Returns the name of the variable. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariable:: -get_name() const { - return _core->get_name(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::get_value_type -// Access: Published -// Description: Returns the stated type of this variable. If the -// variable has not yet been defined, this will be -// VT_undefined. -//////////////////////////////////////////////////////////////////// -INLINE ConfigVariableCore::ValueType ConfigVariable:: -get_value_type() const { - return _core->get_value_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::get_trust_level -// Access: Published -// Description: Returns the minimum trust_level a prc file must -// demonstrate in order to redefine the value for this -// variable. -1 indicates infinite trust: no prc file -// can redefine it. Arguably, this should be called the -// "mistrust level", since the larger the value, the -// more suspicious we are of prc files. -// -// This value only has effect in a release build. -//////////////////////////////////////////////////////////////////// -INLINE int ConfigVariable:: -get_trust_level() const { - return _core->get_trust_level(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::get_description -// Access: Published -// Description: Returns the one-line description of this variable. -// If the variable has not yet been defined, this will -// be empty. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariable:: -get_description() const { - return _core->get_description(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::get_text -// Access: Published -// Description: Returns the paragraph help text describing the -// purpose of this variable in greater detail than -// get_description(). If the variable has not yet been -// defined, this will be empty. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariable:: -get_text() const { - return _core->get_text(); -} - //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::get_default_value // Access: Published @@ -152,33 +103,6 @@ set_string_value(const string &string_value) { _core->make_local_value()->set_string_value(string_value); } -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::clear_local_value -// Access: Published -// Description: Removes the local value defined for this variable, -// and allows its value to be once again retrieved from -// the .prc files. -// -// Returns true if the value was successfully removed, -// false if it did not exist in the first place. -//////////////////////////////////////////////////////////////////// -INLINE bool ConfigVariable:: -clear_local_value() { - return _core->clear_local_value(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::has_local_value -// Access: Published -// Description: Returns true if this variable's value has been -// shadowed by a local assignment (as created via -// make_local_value()), or false otherwise. -//////////////////////////////////////////////////////////////////// -INLINE bool ConfigVariable:: -has_local_value() const { - return _core->has_local_value(); -} - //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::get_num_words // Access: Published @@ -337,29 +261,3 @@ INLINE void ConfigVariable:: set_double_word(int n, double value) { _core->make_local_value()->set_double_word(n, value); } - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::output -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void ConfigVariable:: -output(ostream &out) const { - _core->output(out); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::write -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void ConfigVariable:: -write(ostream &out) const { - _core->write(out); -} - -INLINE ostream & -operator << (ostream &out, const ConfigVariable &variable) { - variable.output(out); - return out; -} diff --git a/dtool/src/prc/configVariable.cxx b/dtool/src/prc/configVariable.cxx index db0aa6905a..5c4f9df0f1 100644 --- a/dtool/src/prc/configVariable.cxx +++ b/dtool/src/prc/configVariable.cxx @@ -17,27 +17,3 @@ //////////////////////////////////////////////////////////////////// #include "configVariable.h" - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariable::Constructor -// Access: Protected -// Description: This constructor is only intended to be called from a -// specialized ConfigVariableFoo derived class. -//////////////////////////////////////////////////////////////////// -ConfigVariable:: -ConfigVariable(const string &name, ConfigVariableCore::ValueType value_type, - int trust_level, const string &description, - const string &text) : - _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) -{ - _core->set_value_type(value_type); - if (trust_level > -2) { - _core->set_trust_level(trust_level); - } - if (!description.empty()) { - _core->set_description(description); - } - if (!text.empty()) { - _core->set_text(text); - } -} diff --git a/dtool/src/prc/configVariable.h b/dtool/src/prc/configVariable.h index 3912bb05fa..29b8769daa 100644 --- a/dtool/src/prc/configVariable.h +++ b/dtool/src/prc/configVariable.h @@ -20,47 +20,36 @@ #define CONFIGVARIABLE_H #include "dtoolbase.h" -#include "configVariableCore.h" -#include "configDeclaration.h" -#include "configVariableManager.h" +#include "configVariableBase.h" //////////////////////////////////////////////////////////////////// // Class : ConfigVariable // Description : This is a generic, untyped ConfigVariable. It is // also the base class for the typed ConfigVariables, // and contains all of the code common to -// ConfigVariables of all types. +// ConfigVariables of all types (except +// ConfigVariableList, which is a bit of a special +// case). // // Mostly, this class serves as a thin wrapper around // ConfigVariableCore and/or ConfigDeclaration, more or // less duplicating the interface presented there. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG ConfigVariable { +class EXPCL_DTOOLCONFIG ConfigVariable : public ConfigVariableBase { protected: - INLINE ConfigVariable(const string &name, - ConfigVariableCore::ValueType type); - ConfigVariable(const string &name, ConfigVariableCore::ValueType type, - int trust_level, const string &description, - const string &text); + INLINE ConfigVariable(const string &name, ValueType type); + INLINE ConfigVariable(const string &name, ValueType type, + int flags, const string &description); PUBLISHED: INLINE ConfigVariable(const string &name); INLINE ~ConfigVariable(); - INLINE const string &get_name() const; - - INLINE ConfigVariableCore::ValueType get_value_type() const; - INLINE int get_trust_level() const; - INLINE const string &get_description() const; - INLINE const string &get_text() const; INLINE const ConfigDeclaration *get_default_value() const; INLINE string get_string_value() const; INLINE void set_string_value(const string &value); - INLINE bool clear_local_value(); - INLINE bool has_local_value() const; - INLINE int get_num_words() const; INLINE bool has_string_word(int n) const; @@ -77,16 +66,8 @@ PUBLISHED: INLINE void set_bool_word(int n, bool value); INLINE void set_int_word(int n, int value); INLINE void set_double_word(int n, double value); - - INLINE void output(ostream &out) const; - INLINE void write(ostream &out) const; - -protected: - ConfigVariableCore *_core; }; -INLINE ostream &operator << (ostream &out, const ConfigVariable &variable); - #include "configVariable.I" #endif diff --git a/dtool/src/prc/configVariableBase.I b/dtool/src/prc/configVariableBase.I new file mode 100644 index 0000000000..cb71650618 --- /dev/null +++ b/dtool/src/prc/configVariableBase.I @@ -0,0 +1,207 @@ +// Filename: configVariableBase.I +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::Constructor +// Access: Protected +// Description: This constructor is only intended to be called from a +// specialized ConfigVariableFoo derived class. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableBase:: +ConfigVariableBase(const string &name, + ConfigVariableBase::ValueType value_type) : + _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) +{ + _core->set_value_type(value_type); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::Destructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableBase:: +~ConfigVariableBase() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::get_name +// Access: Published +// Description: Returns the name of the variable. +//////////////////////////////////////////////////////////////////// +INLINE const string &ConfigVariableBase:: +get_name() const { + return _core->get_name(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::get_value_type +// Access: Published +// Description: Returns the stated type of this variable. This +// should be VT_list, unless a later variable +// declaration has changed it. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableBase::ValueType ConfigVariableBase:: +get_value_type() const { + return _core->get_value_type(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::get_flags +// Access: Public +// Description: Returns the flags value as set by set_flags(). This +// includes the trust level and some other settings. +// See the individual methods is_closed(), +// get_trust_level(), etc. to pull out the semantic +// meaning of these flags individually. +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableBase:: +get_flags() const { + return _core->get_flags(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::is_closed +// Access: Public +// Description: Returns true if the variable is not trusted by any +// prc file (and hence cannot be modified from its +// compiled-in default value), or false for the normal +// case, in which the variable can be modified by any +// prc file at or above its trust level (see +// get_trust_level()). +// +// This value only has effect in a release build +// (specifically, when PRC_RESPECT_TRUST_LEVEL is +// defined true in Config.pp). +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableBase:: +is_closed() const { + return _core->is_closed(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::get_trust_level +// Access: Public +// Description: Returns the minimum trust_level a prc file must +// demonstrate in order to redefine the value for this +// variable. Arguably, this should be called the +// "mistrust level", since the larger the value, the +// more suspicious we are of prc files. This value is +// not used if is_closed() returns true, which indicates +// no file may be trusted. +// +// This value only has effect in a release build +// (specifically, when PRC_RESPECT_TRUST_LEVEL is +// defined true in Config.pp). +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableBase:: +get_trust_level() const { + return _core->get_trust_level(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::is_dynamic +// Access: Public +// Description: Returns true if the variable was indicated as +// "dynamic" by its constructor, indicating that its +// name was dynamically generated, possibly from a large +// pool, and it should not be listed along with the +// other variables. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableBase:: +is_dynamic() const { + return _core->is_dynamic(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::get_description +// Access: Published +// Description: Returns the one-line description of this variable. +// If the variable has not yet been defined, this will +// be empty. +//////////////////////////////////////////////////////////////////// +INLINE const string &ConfigVariableBase:: +get_description() const { + return _core->get_description(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::clear_local_value +// Access: Published +// Description: Removes the local value defined for this variable, +// and allows its value to be once again retrieved from +// the .prc files. +// +// Returns true if the value was successfully removed, +// false if it did not exist in the first place. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableBase:: +clear_local_value() { + return _core->clear_local_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::has_local_value +// Access: Published +// Description: Returns true if this variable's value has been +// shadowed by a local assignment (as created via +// make_local_value()), or false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableBase:: +has_local_value() const { + return _core->has_local_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::has_value +// Access: Public +// Description: Returns true if this variable has an explicit value, +// either from a prc file or locally set, or false if +// variable has its default value. +//////////////////////////////////////////////////////////////////// +bool ConfigVariableBase:: +has_value() const { + return _core->has_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::output +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableBase:: +output(ostream &out) const { + _core->output(out); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::write +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableBase:: +write(ostream &out) const { + _core->write(out); +} + +INLINE ostream & +operator << (ostream &out, const ConfigVariableBase &variable) { + variable.output(out); + return out; +} diff --git a/dtool/src/prc/configVariableBase.cxx b/dtool/src/prc/configVariableBase.cxx new file mode 100644 index 0000000000..f11ce6b2c6 --- /dev/null +++ b/dtool/src/prc/configVariableBase.cxx @@ -0,0 +1,40 @@ +// Filename: configVariableBase.cxx +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#include "configVariableBase.h" + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableBase::Constructor +// Access: Protected +// Description: This constructor is only intended to be called from a +// specialized ConfigVariableFoo derived class. +//////////////////////////////////////////////////////////////////// +ConfigVariableBase:: +ConfigVariableBase(const string &name, + ConfigVariableBase::ValueType value_type, + int flags, const string &description) : + _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) +{ + _core->set_value_type(value_type); + if (flags != 0) { + _core->set_flags(flags); + } + if (!description.empty()) { + _core->set_description(description); + } +} diff --git a/dtool/src/prc/configVariableBase.h b/dtool/src/prc/configVariableBase.h new file mode 100644 index 0000000000..7a3c174a2f --- /dev/null +++ b/dtool/src/prc/configVariableBase.h @@ -0,0 +1,73 @@ +// Filename: configVariableBase.h +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 CONFIGVARIABLEBASE_H +#define CONFIGVARIABLEBASE_H + +#include "dtoolbase.h" +#include "configFlags.h" +#include "configVariableCore.h" +#include "configDeclaration.h" +#include "configVariableManager.h" +#include "vector_string.h" + +//////////////////////////////////////////////////////////////////// +// Class : ConfigVariableBase +// Description : This class is the base class for both +// ConfigVariableList and ConfigVariable (and hence for +// all of the ConfigVariableBool, ConfigVaribleString, +// etc. classes). It collects together the common +// interface for all generic ConfigVariables. +// +// Mostly, this class serves as a thin wrapper around +// ConfigVariableCore and/or ConfigDeclaration, more or +// less duplicating the interface presented there. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOLCONFIG ConfigVariableBase : public ConfigFlags { +protected: + INLINE ConfigVariableBase(const string &name, ValueType type); + ConfigVariableBase(const string &name, ValueType type, + int flags, const string &description); + INLINE ~ConfigVariableBase(); + +PUBLISHED: + INLINE const string &get_name() const; + + INLINE ValueType get_value_type() const; + INLINE int get_flags() const; + INLINE bool is_closed() const; + INLINE int get_trust_level() const; + INLINE bool is_dynamic() const; + INLINE const string &get_description() const; + + INLINE bool clear_local_value(); + INLINE bool has_local_value() const; + INLINE bool has_value() const; + + INLINE void output(ostream &out) const; + INLINE void write(ostream &out) const; + +protected: + ConfigVariableCore *_core; +}; + +INLINE ostream &operator << (ostream &out, const ConfigVariableBase &variable); + +#include "configVariableBase.I" + +#endif diff --git a/dtool/src/prc/configVariableBool.I b/dtool/src/prc/configVariableBool.I index b576ebe85a..4500b177c4 100644 --- a/dtool/src/prc/configVariableBool.I +++ b/dtool/src/prc/configVariableBool.I @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////// INLINE ConfigVariableBool:: ConfigVariableBool(const string &name) : - ConfigVariable(name, ConfigVariableCore::VT_bool) + ConfigVariable(name, VT_bool) { _core->set_used(); } @@ -35,10 +35,9 @@ ConfigVariableBool(const string &name) : // Description: //////////////////////////////////////////////////////////////////// INLINE ConfigVariableBool:: -ConfigVariableBool(const string &name, bool default_value, int trust_level, - const string &description, const string &text) : - ConfigVariable(name, ConfigVariableCore::VT_bool, trust_level, - description, text) +ConfigVariableBool(const string &name, bool default_value, int flags, + const string &description) : + ConfigVariable(name, VT_bool, flags, description) { _core->set_default_value(default_value ? "1" : "0"); _core->set_used(); diff --git a/dtool/src/prc/configVariableBool.h b/dtool/src/prc/configVariableBool.h index 734151670a..2dee06feca 100644 --- a/dtool/src/prc/configVariableBool.h +++ b/dtool/src/prc/configVariableBool.h @@ -31,9 +31,8 @@ class EXPCL_DTOOLCONFIG ConfigVariableBool : public ConfigVariable { PUBLISHED: INLINE ConfigVariableBool(const string &name); INLINE ConfigVariableBool(const string &name, bool default_value, - int trust_level = -2, - const string &description = string(), - const string &text = string()); + int flags = 0, + const string &description = string()); INLINE void operator = (bool value); INLINE operator bool () const; diff --git a/dtool/src/prc/configVariableCore.I b/dtool/src/prc/configVariableCore.I index 8eb3a37afb..bef89686fe 100644 --- a/dtool/src/prc/configVariableCore.I +++ b/dtool/src/prc/configVariableCore.I @@ -50,21 +50,71 @@ get_value_type() const { return _value_type; } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableCore::get_flags +// Access: Public +// Description: Returns the flags value as set by set_flags(). This +// includes the trust level and some other settings. +// See the individual methods is_closed(), +// get_trust_level(), etc. to pull out the semantic +// meaning of these flags individually. +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableCore:: +get_flags() const { + return _flags; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableCore::is_closed +// Access: Public +// Description: Returns true if the variable is not trusted by any +// prc file (and hence cannot be modified from its +// compiled-in default value), or false for the normal +// case, in which the variable can be modified by any +// prc file at or above its trust level (see +// get_trust_level()). +// +// This value only has effect in a release build +// (specifically, when PRC_RESPECT_TRUST_LEVEL is +// defined true in Config.pp). +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableCore:: +is_closed() const { + return (_flags & F_closed) != 0; +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariableCore::get_trust_level // Access: Public // Description: Returns the minimum trust_level a prc file must // demonstrate in order to redefine the value for this -// variable. -1 indicates infinite trust: no prc file -// can redefine it. Arguably, this should be called the +// variable. Arguably, this should be called the // "mistrust level", since the larger the value, the -// more suspicious we are of prc files. +// more suspicious we are of prc files. This value is +// not used if is_closed() returns true, which indicates +// no file may be trusted. // -// This value only has effect in a release build. +// This value only has effect in a release build +// (specifically, when PRC_RESPECT_TRUST_LEVEL is +// defined true in Config.pp). //////////////////////////////////////////////////////////////////// INLINE int ConfigVariableCore:: get_trust_level() const { - return _trust_level; + return (_flags & F_trust_level_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableCore::is_dynamic +// Access: Public +// Description: Returns true if the variable was indicated as +// "dynamic" by its constructor, indicating that its +// name was dynamically generated, possibly from a large +// pool, and it should not be listed along with the +// other variables. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableCore:: +is_dynamic() const { + return (_flags & F_dynamic) != 0; } //////////////////////////////////////////////////////////////////// @@ -79,19 +129,6 @@ get_description() const { return _description; } -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableCore::get_text -// Access: Public -// Description: Returns the paragraph help text describing the -// purpose of this variable in greater detail than -// get_description(). If the variable has not yet been -// defined, this will be empty. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariableCore:: -get_text() const { - return _text; -} - //////////////////////////////////////////////////////////////////// // Function: ConfigVariableCore::get_default_value // Access: Public @@ -127,6 +164,20 @@ has_local_value() const { return _local_value != (ConfigDeclaration *)NULL; } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableCore::get_value_seq +// Access: Public +// Description: Returns a sequence number that changes every time the +// value of the variable might have changed. This is +// useful for caching values from the variable, and +// detecting when the cache has expired. It is +// initially zero and will increment from there. +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableCore:: +get_value_seq() const { + return _value_seq; +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariableCore::get_num_references // Access: Public @@ -154,10 +205,8 @@ get_num_references() const { INLINE const ConfigDeclaration *ConfigVariableCore:: get_reference(int n) const { check_sort_declarations(); - if (n >= 0 && n < (int)_declarations.size()) { - return _declarations[n]; - } - return NULL; + nassertr(n >= 0 && n < (int)_declarations.size(), NULL); + return _declarations[n]; } //////////////////////////////////////////////////////////////////// @@ -190,10 +239,8 @@ get_num_trusted_references() const { INLINE const ConfigDeclaration *ConfigVariableCore:: get_trusted_reference(int n) const { check_sort_declarations(); - if (n >= 0 && n < (int)_trusted_declarations.size()) { - return _trusted_declarations[n]; - } - return NULL; + nassertr(n >= 0 && n < (int)_trusted_declarations.size(), NULL); + return _trusted_declarations[n]; } //////////////////////////////////////////////////////////////////// @@ -219,10 +266,8 @@ get_num_unique_references() const { INLINE const ConfigDeclaration *ConfigVariableCore:: get_unique_reference(int n) const { check_sort_declarations(); - if (n >= 0 && n < (int)_unique_declarations.size()) { - return _unique_declarations[n]; - } - return NULL; + nassertr(n >= 0 && n < (int)_unique_declarations.size(), NULL); + return _unique_declarations[n]; } //////////////////////////////////////////////////////////////////// diff --git a/dtool/src/prc/configVariableCore.cxx b/dtool/src/prc/configVariableCore.cxx index c9f617c79b..df76154fc8 100644 --- a/dtool/src/prc/configVariableCore.cxx +++ b/dtool/src/prc/configVariableCore.cxx @@ -37,11 +37,12 @@ ConfigVariableCore(const string &name) : _name(name), _is_used(false), _value_type(VT_undefined), - _trust_level(0), + _flags(0), _default_value(NULL), _local_value(NULL), _declarations_sorted(true), - _value_queried(false) + _value_queried(false), + _value_seq(0) { } @@ -87,23 +88,23 @@ set_value_type(ConfigVariableCore::ValueType value_type) { } //////////////////////////////////////////////////////////////////// -// Function: ConfigVariableCore::set_trust_level +// Function: ConfigVariableCore::set_flags // Access: Public // Description: Specifies the trust level of this variable. See -// get_trust_level(). It is not an error to call this +// get_flags(). It is not an error to call this // multiple times, but if the value changes once // get_declaration() has been called, a warning is printed. //////////////////////////////////////////////////////////////////// void ConfigVariableCore:: -set_trust_level(int trust_level) { - if (_value_queried && _trust_level != trust_level) { +set_flags(int flags) { + if (_value_queried && _flags != flags) { prc_cat->warning() << "changing trust level for ConfigVariable " - << get_name() << " from " << _trust_level << " to " - << trust_level << ".\n"; + << get_name() << " from " << _flags << " to " + << flags << ".\n"; } - _trust_level = trust_level; + _flags = flags; // Changing the trust level will require re-sorting the // declarations. @@ -136,25 +137,6 @@ set_description(const string &description) { _description = description; } -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableCore::set_text -// Access: Public -// Description: Specifies the long text description of this variable. -// See get_text(). It is not an error to call -// this multiple times, but if the value changes once -// get_declaration() has been called, a warning is printed. -//////////////////////////////////////////////////////////////////// -void ConfigVariableCore:: -set_text(const string &text) { - if (_value_queried && _text != text) { - prc_cat->warning() - << "changing text for ConfigVariable " - << get_name() << ".\n"; - } - - _text = text; -} - //////////////////////////////////////////////////////////////////// // Function: ConfigVariableCore::set_default_value // Access: Public @@ -208,8 +190,20 @@ make_local_value() { ConfigPage *local_page = ConfigPage::get_local_page(); string string_value = get_declaration(0)->get_string_value(); _local_value = local_page->make_declaration(this, string_value); + + if (is_closed()) { + prc_cat.warning() + << "Assigning a local value to a \"closed\" ConfigVariable. " + "This is legal in a development build, but illegal in a release " + "build and may result in a compilation error or exception.\n"; + } } + // Assume that everytime someone asks for the local value, they're + // about to change it; further assume that no one changes the local + // value without calling this method immediately before. + _value_seq++; + return _local_value; } @@ -228,12 +222,29 @@ clear_local_value() { if (_local_value != (ConfigDeclaration *)NULL) { ConfigPage::get_local_page()->delete_declaration(_local_value); _local_value = NULL; + _value_seq++; return true; } return false; } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableCore::has_value +// Access: Public +// Description: Returns true if this variable has an explicit value, +// either from a prc file or locally set, or false if +// variable has its default value. +//////////////////////////////////////////////////////////////////// +bool ConfigVariableCore:: +has_value() const { + if (has_local_value()) { + return true; + } + check_sort_declarations(); + return (!_trusted_declarations.empty()); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariableCore::get_num_declarations // Access: Public @@ -343,6 +354,10 @@ add_declaration(ConfigDeclaration *decl) { _declarations.push_back(decl); _declarations_sorted = false; + + if (!has_local_value()) { + _value_seq++; + } } //////////////////////////////////////////////////////////////////// @@ -365,6 +380,9 @@ remove_declaration(ConfigDeclaration *decl) { (*di) = (*di2); _declarations.erase(di2); _declarations_sorted = false; + if (!has_local_value()) { + _value_seq++; + } return; } } @@ -402,7 +420,7 @@ sort_declarations() { _untrusted_declarations.clear(); for (di = _declarations.begin(); di != _declarations.end(); ++di) { const ConfigDeclaration *decl = (*di); - if (get_trust_level() >= 0 && + if (!is_closed() && get_trust_level() <= decl->get_page()->get_trust_level()) { _trusted_declarations.push_back(decl); } else { @@ -436,32 +454,3 @@ sort_declarations() { _declarations_sorted = true; } - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableCore::Type output operator -// Description: -//////////////////////////////////////////////////////////////////// -ostream & -operator << (ostream &out, ConfigVariableCore::ValueType type) { - switch (type) { - case ConfigVariableCore::VT_undefined: - return out << "undefined"; - - case ConfigVariableCore::VT_list: - return out << "list"; - - case ConfigVariableCore::VT_string: - return out << "string"; - - case ConfigVariableCore::VT_bool: - return out << "bool"; - - case ConfigVariableCore::VT_int: - return out << "int"; - - case ConfigVariableCore::VT_double: - return out << "double"; - } - - return out << "**invalid(" << (int)type << ")**"; -} diff --git a/dtool/src/prc/configVariableCore.h b/dtool/src/prc/configVariableCore.h index b9d23229be..5c8643f6e1 100644 --- a/dtool/src/prc/configVariableCore.h +++ b/dtool/src/prc/configVariableCore.h @@ -20,7 +20,9 @@ #define CONFIGVARIABLECORE_H #include "dtoolbase.h" +#include "configFlags.h" #include "configPageManager.h" +#include "notify.h" #include "pvector.h" #include "pmap.h" @@ -37,34 +39,26 @@ class ConfigDeclaration; // return a shared instance. Once created, these // objects are never destructed. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG ConfigVariableCore { +class EXPCL_DTOOLCONFIG ConfigVariableCore : public ConfigFlags { private: ConfigVariableCore(const string &name); ~ConfigVariableCore(); public: - enum ValueType { - VT_undefined, - VT_list, - VT_string, - VT_bool, - VT_int, - VT_double, - }; - INLINE const string &get_name() const; INLINE bool is_used() const; INLINE ValueType get_value_type() const; + INLINE int get_flags() const; + INLINE bool is_closed() const; INLINE int get_trust_level() const; + INLINE bool is_dynamic() const; INLINE const string &get_description() const; - INLINE const string &get_text() const; INLINE const ConfigDeclaration *get_default_value() const; void set_value_type(ValueType value_type); - void set_trust_level(int trust_level); + void set_flags(int flags); void set_description(const string &description); - void set_text(const string &text); void set_default_value(const string &default_value); INLINE void set_used(); @@ -72,9 +66,12 @@ public: bool clear_local_value(); INLINE bool has_local_value() const; + bool has_value() const; int get_num_declarations() const; const ConfigDeclaration *get_declaration(int n) const; + INLINE int get_value_seq() const; + INLINE int get_num_references() const; INLINE const ConfigDeclaration *get_reference(int n) const; @@ -98,9 +95,8 @@ private: string _name; bool _is_used; ValueType _value_type; - int _trust_level; + int _flags; string _description; - string _text; ConfigDeclaration *_default_value; ConfigDeclaration *_local_value; @@ -111,6 +107,7 @@ private: Declarations _unique_declarations; bool _declarations_sorted; bool _value_queried; + int _value_seq; friend class ConfigDeclaration; friend class ConfigVariableManager; @@ -118,8 +115,6 @@ private: INLINE ostream &operator << (ostream &out, const ConfigVariableCore &variable); -ostream &operator << (ostream &out, ConfigVariableCore::ValueType type); - #include "configVariableCore.I" #endif diff --git a/dtool/src/prc/configVariableDouble.I b/dtool/src/prc/configVariableDouble.I index 2fa2283d1b..6e3ce6fa30 100644 --- a/dtool/src/prc/configVariableDouble.I +++ b/dtool/src/prc/configVariableDouble.I @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////// INLINE ConfigVariableDouble:: ConfigVariableDouble(const string &name) : - ConfigVariable(name, ConfigVariableCore::VT_double) + ConfigVariable(name, VT_double) { _core->set_used(); } diff --git a/dtool/src/prc/configVariableDouble.cxx b/dtool/src/prc/configVariableDouble.cxx index 1cea06fab7..8cbf63d1fb 100644 --- a/dtool/src/prc/configVariableDouble.cxx +++ b/dtool/src/prc/configVariableDouble.cxx @@ -24,10 +24,9 @@ // Description: //////////////////////////////////////////////////////////////////// ConfigVariableDouble:: -ConfigVariableDouble(const string &name, double default_value, int trust_level, - const string &description, const string &text) : - ConfigVariable(name, ConfigVariableCore::VT_double, trust_level, - description, text) +ConfigVariableDouble(const string &name, double default_value, int flags, + const string &description) : + ConfigVariable(name, ConfigVariableCore::VT_double, flags, description) { ostringstream strm; strm << default_value; diff --git a/dtool/src/prc/configVariableDouble.h b/dtool/src/prc/configVariableDouble.h index 6688179158..7c6795118e 100644 --- a/dtool/src/prc/configVariableDouble.h +++ b/dtool/src/prc/configVariableDouble.h @@ -31,9 +31,8 @@ class EXPCL_DTOOLCONFIG ConfigVariableDouble : public ConfigVariable { PUBLISHED: INLINE ConfigVariableDouble(const string &name); ConfigVariableDouble(const string &name, double default_value, - int trust_level = -2, - const string &description = string(), - const string &text = string()); + int flags = 0, + const string &description = string()); INLINE void operator = (double value); INLINE operator double () const; diff --git a/dtool/src/prc/configVariableEnum.I b/dtool/src/prc/configVariableEnum.I new file mode 100644 index 0000000000..30c3f6354f --- /dev/null +++ b/dtool/src/prc/configVariableEnum.I @@ -0,0 +1,188 @@ +// Filename: configVariableEnum.I +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE ConfigVariableEnum:: +ConfigVariableEnum(const string &name, ParseFunc *func, + EnumType default_value, int flags, + const string &description) : + ConfigVariable(name, ConfigVariableCore::VT_enum, flags, description), + _func(func), + _value_seq(-1), + _value(default_value), + _got_default_value(true), + _default_value(default_value) +{ + _core->set_default_value(format_enum(default_value)); + _core->set_used(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE ConfigVariableEnum:: +~ConfigVariableEnum() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::operator = +// Access: Public +// Description: Reassigns the variable's local value. +//////////////////////////////////////////////////////////////////// +template +INLINE void ConfigVariableEnum:: +operator = (EnumType value) { + set_value(value); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::typecast operator +// Access: Public +// Description: Returns the variable's value. +//////////////////////////////////////////////////////////////////// +template +INLINE ConfigVariableEnum:: +operator EnumType () const { + return get_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::size() +// Access: Public +// Description: Returns the number of unique words in the variable. +//////////////////////////////////////////////////////////////////// +template +INLINE int ConfigVariableEnum:: +size() const { + return get_num_words(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::operator [] +// Access: Public +// Description: Returns the value of the variable's nth word. +//////////////////////////////////////////////////////////////////// +template +INLINE EnumType ConfigVariableEnum:: +operator [] (int n) const { + return get_word(n); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::set_value +// Access: Public +// Description: Reassigns the variable's local value. +//////////////////////////////////////////////////////////////////// +template +INLINE void ConfigVariableEnum:: +set_value(EnumType value) { + set_string_value(format_enum(value)); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::get_value +// Access: Public +// Description: Returns the variable's value. +//////////////////////////////////////////////////////////////////// +template +INLINE EnumType ConfigVariableEnum:: +get_value() const { + if (_value_seq != _core->get_value_seq()) { + ((ConfigVariableEnum *)this)->_value = (EnumType)parse_string(get_string_value()); + ((ConfigVariableEnum *)this)->_value_seq = _core->get_value_seq(); + } + return _value; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::get_default_value +// Access: Public +// Description: Returns the variable's default value. +//////////////////////////////////////////////////////////////////// +template +INLINE EnumType ConfigVariableEnum:: +get_default_value() const { + if (!_got_default_value) { + const ConfigDeclaration *decl = ConfigVariable::get_default_value(); + if (decl != (ConfigDeclaration *)NULL) { + ((ConfigVariableEnum *)this)->_default_value = (EnumType)parse_string(decl->get_string_value()); + ((ConfigVariableEnum *)this)->_got_default_value = true; + } + } + return _default_value; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::get_word +// Access: Public +// Description: Returns the variable's nth value. +//////////////////////////////////////////////////////////////////// +template +INLINE EnumType ConfigVariableEnum:: +get_word(int n) const { + return (EnumType)parse_string(get_string_word(n)); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::set_word +// Access: Public +// Description: Reassigns the variable's nth value. This makes a +// local copy of the variable's overall value. +//////////////////////////////////////////////////////////////////// +template +INLINE void ConfigVariableEnum:: +set_word(int n, EnumType value) { + set_string_word(n, format_enum(value)); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::parse_string +// Access: Public, Virtual +// Description: Turns the string value into a value of the enumerated +// type by calling the parse function. +//////////////////////////////////////////////////////////////////// +template +INLINE EnumType ConfigVariableEnum:: +parse_string(const string &value) const { + return (*_func)(value); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableEnum::format_enum +// Access: Public, Virtual +// Description: The format_enum() method assumes the enumerated type +// has a valid operator << (ostream) defined, which +// balances against the parse function passed to the +// constructor. +//////////////////////////////////////////////////////////////////// +template +INLINE string ConfigVariableEnum:: +format_enum(EnumType value) const { + ostringstream strm; + strm << value; + return strm.str(); +} diff --git a/dtool/src/prc/configVariableEnum.cxx b/dtool/src/prc/configVariableEnum.cxx new file mode 100644 index 0000000000..c6afe227e7 --- /dev/null +++ b/dtool/src/prc/configVariableEnum.cxx @@ -0,0 +1,19 @@ +// Filename: configVariableEnum.cxx +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#include "configVariableEnum.h" diff --git a/dtool/src/prc/configVariableEnum.h b/dtool/src/prc/configVariableEnum.h new file mode 100644 index 0000000000..e3f110b9f2 --- /dev/null +++ b/dtool/src/prc/configVariableEnum.h @@ -0,0 +1,79 @@ +// Filename: configVariableEnum.h +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 CONFIGVARIABLEENUM_H +#define CONFIGVARIABLEENUM_H + +#include "dtoolbase.h" +#include "configVariable.h" + +//////////////////////////////////////////////////////////////////// +// Class : ConfigVariableEnum +// Description : This class specializes ConfigVariable as an +// enumerated type. It is a template class, so it +// cannot be easily published; it's not really necessary +// outside of C++ anyway. +// +// This variable assumes that the enumerated type in +// question has an output operator defined that does the +// right thing (outputting a sensible string for the +// type). It also requires a function that converts +// from the strings written by the output operator back +// to the type; this function pointer should be passed +// to the constructor. +//////////////////////////////////////////////////////////////////// +template +class ConfigVariableEnum : public ConfigVariable { +public: + typedef EnumType ParseFunc(const string &value); + + ConfigVariableEnum(const string &name, ParseFunc *func, + EnumType default_value, int flags = 0, + const string &description = string()); + INLINE ~ConfigVariableEnum(); + + INLINE void operator = (EnumType value); + INLINE operator EnumType () const; + + INLINE int size() const; + INLINE EnumType operator [] (int n) const; + + INLINE void set_value(EnumType value); + INLINE EnumType get_value() const; + INLINE EnumType get_default_value() const; + + INLINE EnumType get_word(int n) const; + INLINE void set_word(int n, EnumType value); + +private: + INLINE EnumType parse_string(const string &value) const; + INLINE string format_enum(EnumType value) const; + + ParseFunc *_func; + + int _value_seq; + EnumType _value; + + bool _got_default_value; + EnumType _default_value; +}; + +#include "configVariableEnum.I" + +#endif + diff --git a/dtool/src/prc/configVariableInt.I b/dtool/src/prc/configVariableInt.I index 085fbb1d7b..5495f0558d 100644 --- a/dtool/src/prc/configVariableInt.I +++ b/dtool/src/prc/configVariableInt.I @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////// INLINE ConfigVariableInt:: ConfigVariableInt(const string &name) : - ConfigVariable(name, ConfigVariableCore::VT_int) + ConfigVariable(name, VT_int) { _core->set_used(); } diff --git a/dtool/src/prc/configVariableInt.cxx b/dtool/src/prc/configVariableInt.cxx index 120f05718f..f770a59f17 100644 --- a/dtool/src/prc/configVariableInt.cxx +++ b/dtool/src/prc/configVariableInt.cxx @@ -24,10 +24,9 @@ // Description: //////////////////////////////////////////////////////////////////// ConfigVariableInt:: -ConfigVariableInt(const string &name, int default_value, int trust_level, - const string &description, const string &text) : - ConfigVariable(name, ConfigVariableCore::VT_int, trust_level, - description, text) +ConfigVariableInt(const string &name, int default_value, int flags, + const string &description) : + ConfigVariable(name, ConfigVariableCore::VT_int, flags, description) { ostringstream strm; strm << default_value; diff --git a/dtool/src/prc/configVariableInt.h b/dtool/src/prc/configVariableInt.h index a4dd55bd7f..ea26036631 100644 --- a/dtool/src/prc/configVariableInt.h +++ b/dtool/src/prc/configVariableInt.h @@ -31,9 +31,8 @@ class EXPCL_DTOOLCONFIG ConfigVariableInt : public ConfigVariable { PUBLISHED: INLINE ConfigVariableInt(const string &name); ConfigVariableInt(const string &name, int default_value, - int trust_level = -2, - const string &description = string(), - const string &text = string()); + int flags = 0, + const string &description = string()); INLINE void operator = (int value); INLINE operator int () const; diff --git a/dtool/src/prc/configVariableList.I b/dtool/src/prc/configVariableList.I index ae2552e70d..9e63947ad6 100644 --- a/dtool/src/prc/configVariableList.I +++ b/dtool/src/prc/configVariableList.I @@ -26,70 +26,6 @@ INLINE ConfigVariableList:: ~ConfigVariableList() { } -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::get_name -// Access: Published -// Description: Returns the name of the variable. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariableList:: -get_name() const { - return _core->get_name(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::get_value_type -// Access: Published -// Description: Returns the stated type of this variable. This -// should be VT_list, unless a later variable -// declaration has changed it. -//////////////////////////////////////////////////////////////////// -INLINE ConfigVariableCore::ValueType ConfigVariableList:: -get_value_type() const { - return _core->get_value_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::get_trust_level -// Access: Published -// Description: Returns the minimum trust_level a prc file must -// demonstrate in order to redefine the value for this -// variable. -1 indicates infinite trust: no prc file -// can redefine it. Arguably, this should be called the -// "mistrust level", since the larger the value, the -// more suspicious we are of prc files. -// -// This value only has effect in a release build. -//////////////////////////////////////////////////////////////////// -INLINE int ConfigVariableList:: -get_trust_level() const { - return _core->get_trust_level(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::get_description -// Access: Published -// Description: Returns the one-line description of this variable. -// If the variable has not yet been defined, this will -// be empty. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariableList:: -get_description() const { - return _core->get_description(); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::get_text -// Access: Published -// Description: Returns the paragraph help text describing the -// purpose of this variable in greater detail than -// get_description(). If the variable has not yet been -// defined, this will be empty. -//////////////////////////////////////////////////////////////////// -INLINE const string &ConfigVariableList:: -get_text() const { - return _core->get_text(); -} - //////////////////////////////////////////////////////////////////// // Function: ConfigVariableList::get_num_values // Access: Published @@ -160,29 +96,3 @@ INLINE string ConfigVariableList:: operator [] (int n) const { return get_unique_value(n); } - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::output -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void ConfigVariableList:: -output(ostream &out) const { - _core->output(out); -} - -//////////////////////////////////////////////////////////////////// -// Function: ConfigVariableList::write -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void ConfigVariableList:: -write(ostream &out) const { - _core->write(out); -} - -INLINE ostream & -operator << (ostream &out, const ConfigVariableList &variable) { - variable.output(out); - return out; -} diff --git a/dtool/src/prc/configVariableList.cxx b/dtool/src/prc/configVariableList.cxx index bb7be35834..6940179088 100644 --- a/dtool/src/prc/configVariableList.cxx +++ b/dtool/src/prc/configVariableList.cxx @@ -25,21 +25,9 @@ //////////////////////////////////////////////////////////////////// ConfigVariableList:: ConfigVariableList(const string &name, - int trust_level, const string &description, - const string &text) : - _core(ConfigVariableManager::get_global_ptr()->make_variable(name)) + int flags, const string &description) : + ConfigVariableBase(name, VT_list, flags, description) { - _core->set_value_type(ConfigVariableCore::VT_list); - if (trust_level > -2) { - _core->set_trust_level(trust_level); - } - if (!description.empty()) { - _core->set_description(description); - } - if (!text.empty()) { - _core->set_text(text); - } - // A list variable implicitly defines a default value of the empty // string. This is just to prevent the core variable from // complaining should anyone ask for its solitary value. diff --git a/dtool/src/prc/configVariableList.h b/dtool/src/prc/configVariableList.h index 12e7d4e79a..8f46f22b25 100644 --- a/dtool/src/prc/configVariableList.h +++ b/dtool/src/prc/configVariableList.h @@ -20,10 +20,7 @@ #define CONFIGVARIABLELIST_H #include "dtoolbase.h" -#include "configVariableCore.h" -#include "configDeclaration.h" -#include "configVariableManager.h" -#include "vector_string.h" +#include "configVariableBase.h" //////////////////////////////////////////////////////////////////// // Class : ConfigVariableList @@ -39,20 +36,12 @@ // // A ConfigVariableList cannot be modified locally. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG ConfigVariableList { +class EXPCL_DTOOLCONFIG ConfigVariableList : public ConfigVariableBase { PUBLISHED: - ConfigVariableList(const string &name, int trust_level = -2, - const string &description = string(), - const string &text = string()); + ConfigVariableList(const string &name, int flags = 0, + const string &description = string()); INLINE ~ConfigVariableList(); - INLINE const string &get_name() const; - - INLINE ConfigVariableCore::ValueType get_value_type() const; - INLINE int get_trust_level() const; - INLINE const string &get_description() const; - INLINE const string &get_text() const; - INLINE int get_num_values() const; INLINE string get_string_value(int n) const; @@ -61,17 +50,8 @@ PUBLISHED: INLINE int size() const; INLINE string operator [] (int n) const; - - INLINE void output(ostream &out) const; - INLINE void write(ostream &out) const; - -protected: - ConfigVariableCore *_core; - vector_string _unique_values; }; -INLINE ostream &operator << (ostream &out, const ConfigVariableList &variable); - #include "configVariableList.I" #endif diff --git a/dtool/src/prc/configVariableManager.cxx b/dtool/src/prc/configVariableManager.cxx index da6a9cba3a..6a180bf85a 100644 --- a/dtool/src/prc/configVariableManager.cxx +++ b/dtool/src/prc/configVariableManager.cxx @@ -123,16 +123,18 @@ write(ostream &out) const { ni != _variables_by_name.end(); ++ni) { ConfigVariableCore *variable = (*ni).second; - out << " " << variable->get_name(); - if (!variable->is_used()) { - out << " (not used)"; - } else { - out << " " << variable->get_declaration(0)->get_string_value(); + if (!variable->is_dynamic()) { + out << " " << variable->get_name(); + if (!variable->is_used()) { + out << " (not used)"; + } else { + out << " " << variable->get_declaration(0)->get_string_value(); + } + out << "\n"; } - out << "\n"; } } - + //////////////////////////////////////////////////////////////////// // Function: ConfigVariableManager::list_unused_variables // Access: Published @@ -148,10 +150,10 @@ list_unused_variables() const { ++ni) { ConfigVariableCore *variable = (*ni).second; if (!variable->is_used()) { - cout << variable->get_name() << "\n"; + nout << variable->get_name() << "\n"; int num_references = variable->get_num_references(); for (int i = 0; i < num_references; i++) { - cout << " " << variable->get_reference(i)->get_page()->get_name() + nout << " " << variable->get_reference(i)->get_page()->get_name() << "\n"; } } @@ -171,79 +173,31 @@ list_variables() const { for (ni = _variables_by_name.begin(); ni != _variables_by_name.end(); ++ni) { - ConfigVariableCore *variable = (*ni).second; - if (variable->is_used()) { - - cout << variable->get_name() << " " - << variable->get_value_type() << "\n"; - - const ConfigDeclaration *decl; - - if (variable->get_value_type() == ConfigVariableCore::VT_list) { - // We treat a "list" variable as a special case: list all of - // its values. - cout << " current value =\n"; - int num_references = variable->get_num_trusted_references(); - for (int i = 0; i < num_references; i++) { - decl = variable->get_trusted_reference(i); - cout << " " << decl->get_string_value() - << " (from " << decl->get_page()->get_name() << ")\n"; - } - - } else { - // An ordinary, non-list variable gets one line for its - // current value (if it has one) and another line for its - // default value. - decl = variable->get_declaration(0); - if (decl != variable->get_default_value()) { - cout << " current value = " << decl->get_string_value(); - if (!decl->get_page()->is_special()) { - cout << " (from " << decl->get_page()->get_name() << ")\n"; - } else { - cout << " (defined locally)\n"; - } - } - - decl = variable->get_default_value(); - if (decl != (ConfigDeclaration *)NULL) { - cout << " default value = " << decl->get_string_value() << "\n"; - } - } - - if (!variable->get_description().empty()) { - cout << " " << variable->get_description() << "\n"; - } + const ConfigVariableCore *variable = (*ni).second; + if (variable->is_used() && !variable->is_dynamic()) { + list_variable(variable); } } } //////////////////////////////////////////////////////////////////// -// Function: ConfigVariableManager::describe_variables +// Function: ConfigVariableManager::list_dynamic_variables // Access: Published -// Description: Writes a list of all the variables along with each -// variable's long description. +// Description: Writes a list of all the "dynamic" variables that +// have been declared somewhere in code, along with a +// brief description. This is a (usually large) list of +// config variables that are declared with a generated +// variable name. //////////////////////////////////////////////////////////////////// void ConfigVariableManager:: -describe_variables() const { +list_dynamic_variables() const { VariablesByName::const_iterator ni; for (ni = _variables_by_name.begin(); ni != _variables_by_name.end(); ++ni) { - ConfigVariableCore *variable = (*ni).second; - if (variable->is_used()) { - cout << variable->get_name() << " " - << variable->get_value_type() << "\n"; - - const ConfigDeclaration *decl = variable->get_default_value(); - if (decl != (ConfigDeclaration *)NULL) { - cout << " default value = " << decl->get_string_value() << "\n"; - } - - if (!variable->get_text().empty()) { - cout << " " << variable->get_text() << "\n"; - } else if (!variable->get_description().empty()) { - cout << " " << variable->get_description() << "\n"; - } + const ConfigVariableCore *variable = (*ni).second; + if (variable->is_used() && variable->is_dynamic()) { + list_variable(variable); } } } @@ -260,3 +214,51 @@ get_global_ptr() { } return _global_ptr; } + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableManager::list_variable +// Access: Private +// Description: Lists a single variable and its value. +//////////////////////////////////////////////////////////////////// +void ConfigVariableManager:: +list_variable(const ConfigVariableCore *variable) const { + nout << variable->get_name() << " " + << variable->get_value_type() << "\n"; + + const ConfigDeclaration *decl; + + if (variable->get_value_type() == ConfigVariableCore::VT_list) { + // We treat a "list" variable as a special case: list all of + // its values. + nout << " current value =\n"; + int num_references = variable->get_num_trusted_references(); + for (int i = 0; i < num_references; i++) { + decl = variable->get_trusted_reference(i); + nout << " " << decl->get_string_value() + << " (from " << decl->get_page()->get_name() << ")\n"; + } + + } else { + // An ordinary, non-list variable gets one line for its + // current value (if it has one) and another line for its + // default value. + decl = variable->get_declaration(0); + if (decl != variable->get_default_value()) { + nout << " current value = " << decl->get_string_value(); + if (!decl->get_page()->is_special()) { + nout << " (from " << decl->get_page()->get_name() << ")\n"; + } else { + nout << " (defined locally)\n"; + } + } + + decl = variable->get_default_value(); + if (decl != (ConfigDeclaration *)NULL) { + nout << " default value = " << decl->get_string_value() << "\n"; + } + } + + if (!variable->get_description().empty()) { + nout << " " << variable->get_description() << "\n"; + } +} diff --git a/dtool/src/prc/configVariableManager.h b/dtool/src/prc/configVariableManager.h index fe217e9522..ac03b6bb8f 100644 --- a/dtool/src/prc/configVariableManager.h +++ b/dtool/src/prc/configVariableManager.h @@ -50,11 +50,13 @@ PUBLISHED: void list_unused_variables() const; void list_variables() const; - void describe_variables() const; + void list_dynamic_variables() const; static ConfigVariableManager *get_global_ptr(); private: + void list_variable(const ConfigVariableCore *variable) const; + typedef pvector Variables; Variables _variables; diff --git a/dtool/src/prc/configVariableSearchPath.I b/dtool/src/prc/configVariableSearchPath.I new file mode 100644 index 0000000000..17be7e4703 --- /dev/null +++ b/dtool/src/prc/configVariableSearchPath.I @@ -0,0 +1,214 @@ +// Filename: configVariableSearchPath.I +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableSearchPath:: +~ConfigVariableSearchPath() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::DSearchPath typecast +// Access: Published +// Description: Returns the variable's value. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableSearchPath:: +operator const DSearchPath & () const { + return get_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::clear_local_value +// Access: Published +// Description: Removes all the directories locally added to the +// search list, and restores it to its original form. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableSearchPath:: +clear_local_value() { + bool any_to_clear = !_prefix.is_empty() || _postfix.is_empty(); + _prefix.clear(); + _postfix.clear(); + + if (_core->clear_local_value()) { + any_to_clear = true; + } + + _value_stale = true; + return any_to_clear; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::clear +// Access: Published +// Description: Removes all the directories locally added to the +// search list, and restores it to its original form. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +clear() { + clear_local_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::append_directory +// Access: Published +// Description: Adds a new directory to the end of the search list. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +append_directory(const Filename &directory) { + _postfix.append_directory(directory); + _value_stale = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::prepend_directory +// Access: Published +// Description: Adds a new directory to the front of the search list. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +prepend_directory(const Filename &directory) { + _prefix.prepend_directory(directory); + _value_stale = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::append_path +// Access: Published +// Description: Adds all of the directories listed in the search path +// to the end of the search list. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +append_path(const string &path, const string &separator) { + _postfix.append_path(path, separator); + _value_stale = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::append_path +// Access: Published +// Description: Adds all of the directories listed in the search path +// to the end of the search list. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +append_path(const DSearchPath &path) { + _postfix.append_path(path); + _value_stale = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::prepend_path +// Access: Published +// Description: Adds all of the directories listed in the search path +// to the beginning of the search list. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +prepend_path(const DSearchPath &path) { + _prefix.prepend_path(path); + _value_stale = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::is_empty +// Access: Published +// Description: Returns true if the search list is empty, false +// otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariableSearchPath:: +is_empty() const { + return get_value().is_empty(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::get_num_directories +// Access: Published +// Description: Returns the number of directories on the search list. +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableSearchPath:: +get_num_directories() const { + return get_value().get_num_directories(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::get_directory +// Access: Published +// Description: Returns the nth directory on the search list. +//////////////////////////////////////////////////////////////////// +INLINE const Filename &ConfigVariableSearchPath:: +get_directory(int n) const { + return get_value().get_directory(n); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::find_file +// Access: Published +// Description: Searches all the directories in the search list for +// the indicated file, in order. Returns the full +// matching pathname of the first match if found, or the +// empty string if not found. +//////////////////////////////////////////////////////////////////// +INLINE Filename ConfigVariableSearchPath:: +find_file(const Filename &filename) const { + return get_value().find_file(filename); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::find_all_files +// Access: Published +// Description: Searches all the directories in the search list for +// the indicated file, in order. Fills up the results +// list with *all* of the matching filenames found, if +// any. Returns the number of matches found. +// +// It is the responsibility of the the caller to clear +// the results list first; otherwise, the newly-found +// files will be appended to the list. +//////////////////////////////////////////////////////////////////// +INLINE int ConfigVariableSearchPath:: +find_all_files(const Filename &filename, + DSearchPath::Results &results) const { + return get_value().find_all_files(filename, results); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::output +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +output(ostream &out) const { + get_value().output(out); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::write +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableSearchPath:: +write(ostream &out) const { + get_value().write(out); +} + +INLINE ostream & +operator << (ostream &out, const ConfigVariableSearchPath &variable) { + variable.output(out); + return out; +} diff --git a/dtool/src/prc/configVariableSearchPath.cxx b/dtool/src/prc/configVariableSearchPath.cxx new file mode 100644 index 0000000000..5c63ce1ed4 --- /dev/null +++ b/dtool/src/prc/configVariableSearchPath.cxx @@ -0,0 +1,74 @@ +// Filename: configVariableSearchPath.cxx +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#include "configVariableSearchPath.h" + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +ConfigVariableSearchPath:: +ConfigVariableSearchPath(const string &name, + int flags, const string &description) : + ConfigVariableBase(name, VT_search_path, flags, description), + _value_seq(-1), + _value_stale(true) +{ + // A SearchPath variable implicitly defines a default value of the empty + // string. This is just to prevent the core variable from + // complaining should anyone ask for its solitary value. + if (_core->get_default_value() == (ConfigDeclaration *)NULL) { + _core->set_default_value(""); + } + _core->set_used(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::get_value +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +const DSearchPath &ConfigVariableSearchPath:: +get_value() const { + if (_value_stale || _value_seq != _core->get_value_seq()) { + ((ConfigVariableSearchPath *)this)->reload_search_path(); + } + return _value; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableSearchPath::reload_search_path +// Access: Private +// Description: Recopies the config variable into the search path for +// returning its value. +//////////////////////////////////////////////////////////////////// +void ConfigVariableSearchPath:: +reload_search_path() { + _value.clear(); + + _value.append_path(_prefix); + int num_declarations = _core->get_num_declarations(); + for (int i = 0; i < num_declarations; i++) { + _value.append_directory(_core->get_declaration(i)->get_string_value()); + } + _value.append_path(_postfix); + + _value_seq = _core->get_value_seq(); + _value_stale = false; +} diff --git a/dtool/src/prc/configVariableSearchPath.h b/dtool/src/prc/configVariableSearchPath.h new file mode 100644 index 0000000000..f0c1cdb8bb --- /dev/null +++ b/dtool/src/prc/configVariableSearchPath.h @@ -0,0 +1,90 @@ +// Filename: configVariableSearchPath.h +// Created by: drose (21Oct04) +// +//////////////////////////////////////////////////////////////////// +// +// 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 CONFIGVARIABLESEARCHPATH_H +#define CONFIGVARIABLESEARCHPATH_H + +#include "dtoolbase.h" +#include "configVariableBase.h" +#include "dSearchPath.h" + +//////////////////////////////////////////////////////////////////// +// Class : ConfigVariableSearchPath +// Description : This is similar to a ConfigVariableList, but it +// returns its list as a DSearchPath, as a list of +// directories. +// +// You may locally append directories to the end of the +// search path with the methods here, or prepend them to +// the beginning. Use these methods to make adjustments +// to the path; do not attempt to directly modify the +// const DSearchPath object returned by get_value(). +// +// Unlike other ConfigVariable types, local changes +// (made by calling append_directory() and +// prepend_directory()) are specific to this particular +// instance of the ConfigVariableSearchPath. A separate +// instance of the same variable, created by using the +// same name to the constructor, will not reflect the +// local changes. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOLCONFIG ConfigVariableSearchPath : public ConfigVariableBase { +PUBLISHED: + ConfigVariableSearchPath(const string &name, int flags = 0, + const string &description = string()); + INLINE ~ConfigVariableSearchPath(); + + INLINE operator const DSearchPath & () const; + const DSearchPath &get_value() const; + + INLINE bool clear_local_value(); + + INLINE void clear(); + INLINE void append_directory(const Filename &directory); + INLINE void prepend_directory(const Filename &directory); + INLINE void append_path(const string &path, + const string &separator = string()); + INLINE void append_path(const DSearchPath &path); + INLINE void prepend_path(const DSearchPath &path); + + INLINE bool is_empty() const; + INLINE int get_num_directories() const; + INLINE const Filename &get_directory(int n) const; + + INLINE Filename find_file(const Filename &filename) const; + INLINE int find_all_files(const Filename &filename, + DSearchPath::Results &results) const; + + INLINE void output(ostream &out) const; + INLINE void write(ostream &out) const; + +private: + void reload_search_path(); + + int _value_seq; + bool _value_stale; + + DSearchPath _value; + DSearchPath _prefix, _postfix; +}; + +INLINE ostream &operator << (ostream &out, const ConfigVariableSearchPath &variable); + +#include "configVariableSearchPath.I" + +#endif diff --git a/dtool/src/prc/configVariableString.I b/dtool/src/prc/configVariableString.I index 35963b4bdd..47b49550bc 100644 --- a/dtool/src/prc/configVariableString.I +++ b/dtool/src/prc/configVariableString.I @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////// INLINE ConfigVariableString:: ConfigVariableString(const string &name) : - ConfigVariable(name, ConfigVariableCore::VT_string) + ConfigVariable(name, VT_string) { _core->set_used(); } @@ -35,10 +35,9 @@ ConfigVariableString(const string &name) : // Description: //////////////////////////////////////////////////////////////////// INLINE ConfigVariableString:: -ConfigVariableString(const string &name, string default_value, int trust_level, - const string &description, const string &text) : - ConfigVariable(name, ConfigVariableCore::VT_string, trust_level, - description, text) +ConfigVariableString(const string &name, string default_value, int flags, + const string &description) : + ConfigVariable(name, VT_string, flags, description) { _core->set_default_value(default_value); _core->set_used(); @@ -55,7 +54,7 @@ operator = (const string &value) { } //////////////////////////////////////////////////////////////////// -// Function: ConfigVariableString::typecast operator +// Function: ConfigVariableString::string typecast operator // Access: Published // Description: Returns the variable's value. //////////////////////////////////////////////////////////////////// @@ -64,6 +63,19 @@ operator string () const { return get_value(); } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableString::Filename typecast operator +// Access: Published +// Description: Returns the variable's value. This typecast operator +// is a convenience in case you happen to want to assign +// a ConfigVariableString into a Filename; C++ won't +// make the implicit typecast for you. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableString:: +operator Filename () const { + return get_value(); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariableString::empty // Access: Published diff --git a/dtool/src/prc/configVariableString.h b/dtool/src/prc/configVariableString.h index d9491ee4d2..7fd7da8b07 100644 --- a/dtool/src/prc/configVariableString.h +++ b/dtool/src/prc/configVariableString.h @@ -21,6 +21,7 @@ #include "dtoolbase.h" #include "configVariable.h" +#include "filename.h" //////////////////////////////////////////////////////////////////// // Class : ConfigVariableString @@ -31,12 +32,12 @@ class EXPCL_DTOOLCONFIG ConfigVariableString : public ConfigVariable { PUBLISHED: INLINE ConfigVariableString(const string &name); INLINE ConfigVariableString(const string &name, string default_value, - int trust_level = -2, - const string &description = string(), - const string &text = string()); + int flags = 0, + const string &description = string()); INLINE void operator = (const string &value); INLINE operator string () const; + INLINE operator Filename () const; INLINE bool empty() const; // Comparison operators are handy. diff --git a/dtool/src/prc/configVariableTempl.h b/dtool/src/prc/configVariableTempl.h deleted file mode 100644 index 3b4623edf3..0000000000 --- a/dtool/src/prc/configVariableTempl.h +++ /dev/null @@ -1,41 +0,0 @@ -// Filename: configVariableTempl.h -// Created by: drose (20Oct04) -// -//////////////////////////////////////////////////////////////////// -// -// 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 CONFIGVARIABLETEMPL_H -#define CONFIGVARIABLETEMPL_H - -#include "dtoolbase.h" -#include "configVariable.h" - -//////////////////////////////////////////////////////////////////// -// Class : ConfigVariableTempl -// Description : This is a template class to define ConfigVaribleInt, -// ConfigVariableBool, etc. -//////////////////////////////////////////////////////////////////// -template -class ConfigVariableTempl { -PUBLISHED: - INLINE ConfigVariableTempl(const string &name); - INLINE ConfigVariableTempl(const string &name, ValueType default_value, - int trust_level = -1, - const string &description = string(), - const string &text = string()); - - INLINE operator ValueType () const; - INLINE void operator = (const ValueType &value); - diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index 192f0c0fcb..04c595029e 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "notify.h" +#include "notifyCategory.h" #include "configPageManager.h" #include "configVariableString.h" #include "configVariableBool.h" @@ -539,7 +540,7 @@ config_initialized() { set_ostream_ptr(&cerr, false); } else { - Filename filename = notify_output.get_value(); + Filename filename = notify_output; filename.set_text(); ofstream *out = new ofstream; if (!filename.open_write(*out)) { diff --git a/dtool/src/prc/notify.h b/dtool/src/prc/notify.h index 15aac8e3f6..e38dc12a9b 100644 --- a/dtool/src/prc/notify.h +++ b/dtool/src/prc/notify.h @@ -21,13 +21,14 @@ #include "dtoolbase.h" -#include "notifyCategory.h" #include "notifySeverity.h" #include #include #include +class NotifyCategory; + //////////////////////////////////////////////////////////////////// // Class : Notify // Description : An object that handles general error reporting to the diff --git a/dtool/src/prc/notifyCategory.I b/dtool/src/prc/notifyCategory.I index aa40beba45..b17da76be3 100644 --- a/dtool/src/prc/notifyCategory.I +++ b/dtool/src/prc/notifyCategory.I @@ -37,16 +37,6 @@ get_basename() const { return _basename; } -//////////////////////////////////////////////////////////////////// -// Function: NotifyCategory::get_severity -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE NotifySeverity NotifyCategory:: -get_severity() const { - return _severity; -} - //////////////////////////////////////////////////////////////////// // Function: NotifyCategory::set_severity // Access: Public @@ -67,7 +57,7 @@ set_severity(NotifySeverity severity) { //////////////////////////////////////////////////////////////////// INLINE bool NotifyCategory:: is_on(NotifySeverity severity) const { - return (int)severity >= (int)_severity; + return (int)severity >= (int)get_severity(); } #if defined(NOTIFY_DEBUG) || defined(CPPPARSER) diff --git a/dtool/src/prc/notifyCategory.cxx b/dtool/src/prc/notifyCategory.cxx index 8d6f359520..74c4897464 100644 --- a/dtool/src/prc/notifyCategory.cxx +++ b/dtool/src/prc/notifyCategory.cxx @@ -41,56 +41,43 @@ NotifyCategory(const string &fullname, const string &basename, NotifyCategory *parent) : _fullname(fullname), _basename(basename), - _parent(parent) + _parent(parent), + _severity(get_config_name(), Notify::string_severity, NS_unspecified, + ConfigVariable::F_dynamic) { if (_parent != (NotifyCategory *)NULL) { _parent->_children.push_back(this); } - _severity = NS_unspecified; - - // See if there's a config option to set the severity level for this - // Category. - - string config_name; - - if (_fullname.empty()) { - config_name = "notify-level"; - } else if (!_basename.empty()) { - config_name = "notify-level-" + _basename; - } - - if (!config_name.empty()) { - ConfigVariableString severity_name - (config_name, "", 0, - "Indicates the verbosity level of notify messages for the given category."); - if (!severity_name.empty()) { - // The user specified a particular severity for this category at - // config time. Use it. - _severity = Notify::string_severity(severity_name); - - if (_severity == NS_unspecified) { - nout << "Invalid severity name for " << config_name << ": " - << severity_name << "\n"; - } - } - } - - if (_severity == NS_unspecified) { - // If we didn't get an explicit severity level, inherit our - // parent's. - if (_parent != (NotifyCategory *)NULL) { - _severity = _parent->_severity; - } else { - // Unless, of course, we're the root. - _severity = NS_info; - } - } - // Only the unnamed top category is allowed not to have a parent. nassertv(_parent != (NotifyCategory *)NULL || _fullname.empty()); } +//////////////////////////////////////////////////////////////////// +// Function: NotifyCategory::get_severity +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +NotifySeverity NotifyCategory:: +get_severity() const { + if (_severity == NS_unspecified) { + // If we don't have an explicit severity level, inherit our + // parent's. + if (_severity.has_value()) { + nout << "Invalid severity name for " << _severity.get_name() << ": " + << _severity.get_string_value() << "\n"; + } + if (_parent != (NotifyCategory *)NULL) { + return _parent->get_severity(); + + } else { + // Unless, of course, we're the root. + return NS_info; + } + } + return _severity; +} + //////////////////////////////////////////////////////////////////// // Function: NotifyCategory::out // Access: Published @@ -163,3 +150,22 @@ void NotifyCategory:: set_server_delta(time_t delta) { _server_delta = delta; } + +//////////////////////////////////////////////////////////////////// +// Function: NotifyCategory::get_config_name +// Access: Private +// Description: Returns the name of the config variable that controls +// this category. This is called at construction time. +//////////////////////////////////////////////////////////////////// +string NotifyCategory:: +get_config_name() const { + string config_name; + + if (_fullname.empty()) { + config_name = "notify-level"; + } else if (!_basename.empty()) { + config_name = "notify-level-" + _basename; + } + + return config_name; +} diff --git a/dtool/src/prc/notifyCategory.h b/dtool/src/prc/notifyCategory.h index 38872b1878..57c666eedc 100644 --- a/dtool/src/prc/notifyCategory.h +++ b/dtool/src/prc/notifyCategory.h @@ -22,8 +22,8 @@ #include "dtoolbase.h" #include "notifySeverity.h" - -#include +#include "configVariableEnum.h" +#include "pvector.h" //////////////////////////////////////////////////////////////////// // Class : NotifyCategory @@ -42,7 +42,7 @@ private: PUBLISHED: INLINE string get_fullname() const; INLINE string get_basename() const; - INLINE NotifySeverity get_severity() const; + NotifySeverity get_severity() const; INLINE void set_severity(NotifySeverity severity); INLINE bool is_on(NotifySeverity severity) const; @@ -79,11 +79,13 @@ PUBLISHED: static void set_server_delta(time_t delta); private: + string get_config_name() const; + string _fullname; string _basename; NotifyCategory *_parent; - NotifySeverity _severity; - typedef vector Children; + ConfigVariableEnum _severity; + typedef pvector Children; Children _children; static time_t _server_delta; diff --git a/dtool/src/prc/prcKeyRegistry.cxx b/dtool/src/prc/prcKeyRegistry.cxx index 8ce1fef1e5..7b597bc931 100644 --- a/dtool/src/prc/prcKeyRegistry.cxx +++ b/dtool/src/prc/prcKeyRegistry.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "prcKeyRegistry.h" +#include "config_prc.h" // This file requires OpenSSL to compile, because we use routines in // the OpenSSL library to manage keys and to sign and validate @@ -45,7 +46,8 @@ PrcKeyRegistry() { //////////////////////////////////////////////////////////////////// PrcKeyRegistry:: ~PrcKeyRegistry() { - cerr << "Internal error--PrcKeyRegistry destructor called!\n"; + prc_cat.error() + << "Internal error--PrcKeyRegistry destructor called!\n"; } //////////////////////////////////////////////////////////////////// @@ -134,9 +136,7 @@ get_num_keys() const { //////////////////////////////////////////////////////////////////// EVP_PKEY *PrcKeyRegistry:: get_key(int n) const { - if (n < 0 || n >= (int)_keys.size()) { - return NULL; - } + nassertr(n >= 0 && n < (int)_keys.size(), NULL); if (_keys[n]._def != (KeyDef *)NULL) { if (_keys[n]._pkey == (EVP_PKEY *)NULL) { @@ -165,9 +165,7 @@ get_key(int n) const { //////////////////////////////////////////////////////////////////// time_t PrcKeyRegistry:: get_generated_time(int n) const { - if (n < 0 || n >= (int)_keys.size()) { - return 0; - } + nassertr(n >= 0 && n < (int)_keys.size(), 0); return _keys[n]._generated_time; } diff --git a/dtool/src/prc/prcKeyRegistry.h b/dtool/src/prc/prcKeyRegistry.h index a0d72b1940..079a0d1ae2 100644 --- a/dtool/src/prc/prcKeyRegistry.h +++ b/dtool/src/prc/prcKeyRegistry.h @@ -36,7 +36,7 @@ // verify the signature on a prc file. The actual // public keys themselves are generated by the // make-prc-key utility; the output of this utility is a -// .c file which should be named by the +// .cxx file which should be named by the // PRC_PUBLIC_KEYS_FILENAME variable in Config.pp. // // This class requires the OpenSSL library. diff --git a/dtool/src/pystub/pystub.cxx b/dtool/src/pystub/pystub.cxx index 208abb2716..cdd95c6b8c 100644 --- a/dtool/src/pystub/pystub.cxx +++ b/dtool/src/pystub/pystub.cxx @@ -23,6 +23,7 @@ extern "C" { EXPCL_DTOOLCONFIG int PyErr_Occurred(...); EXPCL_DTOOLCONFIG int PyErr_SetString(...); EXPCL_DTOOLCONFIG int PyExc_TypeError(...); + EXPCL_DTOOLCONFIG int PyDict_GetItem(...); EXPCL_DTOOLCONFIG int PyFloat_AsDouble(...); EXPCL_DTOOLCONFIG int PyFloat_FromDouble(...); EXPCL_DTOOLCONFIG int PyFloat_Type(...); @@ -70,6 +71,7 @@ int PyArg_ParseTuple(...) { return 0; } int PyErr_Occurred(...) { return 0; } int PyErr_SetString(...) { return 0; } int PyExc_TypeError(...) { return 0; } +int PyDict_GetItem(...) { return 0; } int PyFloat_AsDouble(...) { return 0; } int PyFloat_FromDouble(...) { return 0; } int PyFloat_Type(...) { return 0; } diff --git a/dtool/src/test_interrogate/test_interrogate.cxx b/dtool/src/test_interrogate/test_interrogate.cxx index ddd44c377c..0adef25c73 100644 --- a/dtool/src/test_interrogate/test_interrogate.cxx +++ b/dtool/src/test_interrogate/test_interrogate.cxx @@ -26,7 +26,7 @@ #include -#ifndef HAVE_GETOPT_LONG_ONLY +#ifndef HAVE_GETOPT #include "gnu_getopt.h" #else #ifdef HAVE_GETOPT_H @@ -463,6 +463,8 @@ usage() { "files), and will not have any function pointers available.\n\n" "Options:\n\n" + " -p [path]\n" + " Specify the search path for *.in files. This option may be repeated.\n" " -f Give a detailed report of each function in the database, including\n" " synthesized functions like upcasts and downcasts.\n" " -t Give a detailed report of every type in the database, including types\n" @@ -473,9 +475,9 @@ usage() { int main(int argc, char *argv[]) { - // extern char *optarg; + extern char *optarg; extern int optind; - const char *optstr = "ftqh"; + const char *optstr = "p:ftqh"; bool all_functions = false; bool all_types = false; @@ -484,6 +486,10 @@ main(int argc, char *argv[]) { while (flag != EOF) { switch (flag) { + case 'p': + interrogate_add_search_path(optarg); + break; + case 'f': all_functions = true; break; diff --git a/panda/src/express/config_express.N b/panda/src/express/config_express.N index c0b637bef2..4fd7911a86 100644 --- a/panda/src/express/config_express.N +++ b/panda/src/express/config_express.N @@ -8,9 +8,11 @@ forcetype NotifySeverity forcetype ConfigExpress renametype ConfigExpress ConfigExpress +forcetype ConfigFlags forcetype ConfigPage forcetype ConfigPageManager forcetype ConfigVariable +forcetype ConfigVariableBase forcetype ConfigVariableBool forcetype ConfigVariableDouble forcetype ConfigVariableInt diff --git a/panda/src/express/config_express.h b/panda/src/express/config_express.h index ed90a27376..fee25d0de6 100644 --- a/panda/src/express/config_express.h +++ b/panda/src/express/config_express.h @@ -27,9 +27,11 @@ // We include these files to force them to be instrumented by // interrogate. #include "globPattern.h" +#include "configFlags.h" #include "configPage.h" #include "configPageManager.h" #include "configVariable.h" +#include "configVariableBase.h" #include "configVariableBool.h" #include "configVariableDouble.h" #include "configVariableInt.h" diff --git a/panda/src/pstatclient/pStatProperties.cxx b/panda/src/pstatclient/pStatProperties.cxx index 00adbda494..f1447fcc8d 100644 --- a/panda/src/pstatclient/pStatProperties.cxx +++ b/panda/src/pstatclient/pStatProperties.cxx @@ -20,6 +20,10 @@ #include "pStatCollectorDef.h" #include "pStatClient.h" #include "config_pstats.h" +#include "configVariableBool.h" +#include "configVariableDouble.h" +#include "configVariableInt.h" +#include "configVariableString.h" #include @@ -268,44 +272,35 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) { } } - if (!config_pstats.GetString("pstats-active-" + config_name, "").empty()) { - def->_is_active = - config_pstats.GetBool("pstats-active-" + config_name, true); + ConfigVariableBool pstats_active + ("pstats-active-" + config_name, true, ConfigVariable::F_dynamic); + ConfigVariableInt pstats_sort + ("pstats-sort-" + config_name, def->_sort, ConfigVariable::F_dynamic); + ConfigVariableDouble pstats_scale + ("pstats-scale-" + config_name, def->_suggested_scale, ConfigVariable::F_dynamic); + ConfigVariableString pstats_units + ("pstats-units-" + config_name, def->_level_units, ConfigVariable::F_dynamic); + ConfigVariableDouble pstats_factor + ("pstats-factor-" + config_name, 1.0, ConfigVariable::F_dynamic); + ConfigVariableDouble pstats_color + ("pstats-color-" + config_name, 0.0, ConfigVariable::F_dynamic); + + if (pstats_active.has_value()) { + def->_is_active = pstats_active; def->_active_explicitly_set = true; } - def->_sort = - config_pstats.GetInt("pstats-sort-" + config_name, def->_sort); - def->_suggested_scale = - config_pstats.GetFloat("pstats-scale-" + config_name, def->_suggested_scale); - def->_level_units = - config_pstats.GetString("pstats-units-" + config_name, def->_level_units); - def->_level_units = - config_pstats.GetString("pstats-units-" + config_name, def->_level_units); - if (!config_pstats.GetString("pstats-factor-" + config_name, "").empty()) { - def->_factor = - 1.0/config_pstats.GetFloat("pstats-factor-" + config_name, 1.0); + def->_sort = pstats_sort; + def->_suggested_scale = pstats_scale; + def->_level_units = pstats_units; + if (pstats_factor.has_value()) { + def->_factor = pstats_factor; } - // Get and decode the color string. We allow any three - // floating-point numbers, with any kind of non-digit characters - // between them. - string color_str = - config_pstats.GetString("pstats-color-" + config_name, ""); - if (!color_str.empty()) { - const char *cstr = color_str.c_str(); - const char *p = cstr; - - int i = 0; - while (i < 3 && *p != '\0') { - while (*p != '\0' && !(isdigit(*p) || *p == '.')) { - p++; - } - char *q; - def->_suggested_color[i] = strtod(p, &q); - p = q; - i++; - } + if (pstats_color.has_value()) { + def->_suggested_color[0] = pstats_color[0]; + def->_suggested_color[1] = pstats_color[1]; + def->_suggested_color[2] = pstats_color[2]; } } diff --git a/panda/src/putil/Sources.pp b/panda/src/putil/Sources.pp index ee426e4d28..aa76e3faba 100644 --- a/panda/src/putil/Sources.pp +++ b/panda/src/putil/Sources.pp @@ -34,6 +34,7 @@ ioPtaDatagramFloat.h ioPtaDatagramInt.h \ ioPtaDatagramShort.h keyboardButton.h lineStream.I \ lineStream.h lineStreamBuf.I lineStreamBuf.h \ + load_prc_file.h \ modifierButtons.I modifierButtons.h mouseButton.h \ mouseData.I mouseData.h nameUniquifier.I nameUniquifier.h \ pipeline.h pipeline.I \ @@ -64,6 +65,7 @@ globalPointerRegistry.cxx ioPtaDatagramFloat.cxx \ ioPtaDatagramInt.cxx ioPtaDatagramShort.cxx \ keyboardButton.cxx lineStream.cxx lineStreamBuf.cxx \ + load_prc_file.cxx \ modifierButtons.cxx mouseButton.cxx mouseData.cxx \ nameUniquifier.cxx \ pipeline.cxx \ @@ -101,7 +103,9 @@ indirectCompareTo.h \ ioPtaDatagramFloat.h ioPtaDatagramInt.h \ ioPtaDatagramShort.h iterator_types.h keyboardButton.h lineStream.I \ - lineStream.h lineStreamBuf.I lineStreamBuf.h modifierButtons.I \ + lineStream.h lineStreamBuf.I lineStreamBuf.h \ + load_prc_file.h \ + modifierButtons.I \ modifierButtons.h mouseButton.h mouseData.I mouseData.h \ nameUniquifier.I nameUniquifier.h \ pipeline.h pipeline.I \ diff --git a/panda/src/putil/putil_composite1.cxx b/panda/src/putil/putil_composite1.cxx index 95219654b1..c9e585db24 100644 --- a/panda/src/putil/putil_composite1.cxx +++ b/panda/src/putil/putil_composite1.cxx @@ -21,6 +21,7 @@ #include "keyboardButton.cxx" #include "lineStream.cxx" #include "lineStreamBuf.cxx" +#include "load_prc_file.cxx" #include "modifierButtons.cxx" #include "mouseButton.cxx" #include "mouseData.cxx"