Browse Source

document in progress

David Rose 21 years ago
parent
commit
d2df1238df
1 changed files with 516 additions and 0 deletions
  1. 516 0
      panda/src/doc/howto.use_config.txt

+ 516 - 0
panda/src/doc/howto.use_config.txt

@@ -0,0 +1,516 @@
+This document describes the use of the Panda's Config.prc
+configuration files and the runtime subsystem that extracts values
+from these files, defined in dtool/src/prc.
+
+The Config.prc files are used for runtime configuration only, and are
+not related to the Config.pp files, which control compile-time
+configuration.  If you are looking for documentation on the Config.pp
+files, see howto.use_ppremake.txt, and ppremake-*.txt, in this
+directory.
+
+
+USING THE PRC FILES
+
+In its default mode, when Panda starts up it will search in the
+install/etc directory (or in the directory named by the environment
+variable PRC_DIR if it is set) for all files named *.prc (that is, any
+files with an extension of "prc") and read each of them for runtime
+configuration.  (It is possible to change this default behavior; see
+CHANGING THE DEFAULT STARTUP BEHAVIOR, below.)
+
+All of the prc files are loaded in alphabetical order, so that the
+files that have the alphabetically later names are loaded last. Since
+variables defined in an later file may shadow variables defined in an
+earlier file, this means that filenames towards the end of the
+alphabet have the most precedence.
+
+Panda by default installs a handful of system prc files into the
+install/etc directory.  These files have names beginning with digits,
+like 20_panda.prc and 40_direct.prc, so that they will be loaded in a
+particular order.  If you create your own prc file in this directory,
+we recommended that you begin its filename with letters, so that it
+will sort to the bottom of the list and will therefore override any of
+the default variables defined in the system prc files.
+
+
+Within a particular prc file, you may define any number of
+configuration variables and their associated value.  Each definition
+must appear one per line, with at least one space separating the
+variable and its definition, e.g.:
+
+load-display pandagl
+
+This specifies that the variable "load-display" should have the value
+"pandagl".
+
+Comments may also appear in the file; they are introduced by a leading
+hash mark (#).  A comment must be on a line by itself; you may not
+place a comment on the same line with a variable definition.
+
+
+The legal values that you may specify for any particular variable
+depends on the variable.  The complete list of available variables and
+the valid values for each is not documented here (a list of the most
+commonly modified variables appears in another document, but also see
+cvMgr.listVariables(), below).
+
+Many variables accept any string value (such as load-display, above);
+many others, such as aspect-ratio, expect a numeric value.
+
+A large number of variables expect a simple boolean true/false value.
+You may observe the Python convention of using 0 vs. 1 to represent
+false vs. true; or you may literally type "false" or "true", or just
+"f" and "t".  For historical reasons, Panda also recognizes the Scheme
+convention of "#f" and "#t".
+
+
+Most variables only accept one value at a time.  If there are two
+different definitions for a given variable in the same file, the
+topmost definition applies.  If there are two different definitions in
+two different files, the definition given in the file loaded later
+applies.
+
+However, some variables accept multiple values.  This is particularly
+common for variables that name search directories, like model-path.
+In the case of these variables, all definitions given for the variable
+are taken together; it is possible to extend the definition by adding
+another prc file, but you cannot completely hide any value defined in
+a previously-loaded prc file.
+
+
+DEFINING CONFIG VARIABLES
+
+New config variables may be defined on-the-fly in either C++ or Python
+code.  To do this, create an instance of one of the following classes:
+
+ConfigVariableString
+ConfigVariableBool
+ConfigVariableInt
+ConfigVariableDouble
+ConfigVariableEnum (C++ only)
+ConfigVariableList
+ConfigVariableSearchPath
+
+These each define a config variable of the corresponding type.  For
+instance, a ConfigVariableInt defines a variable whose value must
+always be an integer value.  The most common variable types are the
+top four, which are self-explanatory; the remaining three are special
+types:
+
+ConfigVariableEnum -
+
+  This is a special template class available in C++ only.  It provides
+  a convenient way to define a variable that may accept any of a
+  handful of different values, each of which is defined by a keyword.
+  For instance, the text-encoding variable may be set to any of
+  "iso8859", "utf8", or "unicode", which correspond to
+  TextEncoder::E_iso8859, E_utf8, and E_unicode, respectively.
+
+  The ConfigVariableEnum class relies on a having sensible pair of
+  functions defined for operator << (ostream) and operator >>
+  (istream) for the enumerated type.  These two functions should
+  reverse each other, so that the output operator generates a keyword
+  for each value of the enumerated type, and the input operator
+  recognizes each of the keywords generated by the output operator.
+
+  This is a template class.  It is templated on its enumerated type,
+  e.g. ConfigVariableEnum<TextEncoder::Encoding>.
+
+ConfigVariableList -
+
+  This class defines a special config variable that records all of its
+  definitions appearing in all prc files and retrieves them as a list,
+  instead of a standard config variable that returns only the topmost
+  definition.  (See "some variables accept multiple values", above.)
+
+  Unlike the other kinds of config variables, a ConfigVariableList is
+  read-only; it can be modified only by loading additional prc files,
+  rather than directly setting its value.  Also, its constructor lacks
+  a default_value parameter (there is no default value; if the
+  variable is not defined in any prc file, it simply returns an empty
+  list).
+
+ConfigVariableSearchPath -
+
+  This class is very similar to a ConfigVariableList, above, except
+  that it is intended specifically to represent the multiple
+  directories of a search path.  In general, a
+  ConfigVariableSearchPath variable can be used in place of a
+  DSearchPath variable.
+
+  Unlike ConfigVariableList, instances of this variable can be locally
+  modified by appending or prepending additional directory names.
+
+
+In general, each of the constructors to the above classes accepts the
+following parameters:
+
+(name, default_value, description = "", flags = 0)
+
+The default_value parameter should be of the same type as the variable
+itself; for instance, the default_value for a ConfigVariableBool must
+be either true or false.  The ConfigVariableList and
+ConfigVariableSearchPath constructors do not have a default_value
+parameter.
+
+The description should be a sentence or two describing the purpose of
+the variable and the effects of setting it.  It will be reported with
+variable.getDescription() or ConfigVariableManager.listVariables();
+see QUERYING CONFIG VARIABLES, below.
+
+The flags variable is usually set to 0, but it may be an integer trust
+level and/or the union of any of the values in the enumerated type
+ConfigFlags::VariableFlags.  For the most part, this is used to
+restrict the variable from being set by unsigned prc files.  See
+SIGNED PRC FILES, below.
+
+Once you have created a config variable of the appropriate type, you
+may generally treat it directly as a simple variable of that type.
+This works in both C++ and in Python.  For instance, you may write
+code such as this:
+
+ConfigVariableInt foo_level("foo-level", -1, "The initial level of foo");
+
+if (foo_level < 0) {
+  cerr << "You didn't specify a valid foo_level!\n";
+
+} else {
+  // Four snarfs for every foo.
+  int snarf_level = 4 * foo_level;
+}
+
+In rare cases, you may find that the implicit typecast operators
+aren't resolved properly by the compiler; if this happens, you can use
+variable.get_value() to retrieve the variable's value explicitly.
+
+
+DIRECTLY ASSIGNING CONFIG VARIABLES
+
+In general, config variables can also be assigned values appropriate
+to their type, again as if they were ordinary variables.  In C++, the
+assignment operator is overloaded to perform this function, e.g.:
+
+  foo_level = 5;
+
+In Python, this is not possible--the assignment operator in Python
+completely replaces the value of the assigned symbol and cannot be
+overloaded.  So the above statement in Python would replace foo_level
+with an actual integer of the value 5.  In many cases, this is close
+enough to what you intended anyway, but if you want to keep the
+original functionality of the config variable (e.g. so you can restore
+it to its original value later), you need to use the set_value()
+method instead, like this:
+
+  fooLevel.setValue(5)
+
+When you assign a variable locally, the new definition shadows all prc
+files that have been read or will ever be read, until you clear your
+definition.  To restore a variable to its original value as defined by
+the topmost prc file, use clear_local_value():
+
+  fooLevel.clearLocalValue()
+
+In general, this interface for assigning config variables is primarily
+intended for the convenience of developing an application
+interactively; it is sometimes useful to change the value of a
+variable on the fly.
+
+
+QUERYING CONFIG VARIABLES
+
+There are several mechanisms for finding out the values of individual
+config variables, as well as for finding the complete list of
+available config variables.
+
+In particular, one easy way to query an existing config variable's
+value is simply to create a new instance, e.g.:
+
+  print ConfigVariableInt("foo-level")
+
+The default value and comment are optional if another instance of the
+same config variable has previously been created, supplying these
+parameters.  However, it is an error if no instance of a particular
+config variable specifies a default value.  It is also an error (but
+it is treated as a warning) if two different instances of a variable
+specify different default values.
+
+(Note that, although it is convenient to create a new instance of the
+variable in order to query or modify its value interactively, we
+recommend that all the references to a particular variable in code
+should reference the same instance wherever possible.  This minimizes
+the potential confusion about which instance should define the
+variable's default value and/or description, and reduces chance of
+conflicts should two such instances differ.)
+
+If you don't know the type of the variable, you can also simply create
+an instance of the generic ConfigVariable class, for the purpose of
+querying an existing variable only (you cannot define a new variable
+with the generic class).
+
+For more detail about a variable, use the ls() method in Python (or
+the write() method in C++), e.g.:
+
+  ConfigVariable("foo-level").ls()
+
+In additional to the variable's current and default values, this also
+prints a breakdown of all of the prc files that contribute to the
+value of the variable, as well as the description passed as the third
+parameter to the primary ConfigVariable constructor.
+
+To get a list of all known config variables, use the methods on
+ConfigVariableManager.  In C++, you can get this object via
+ConfigVariableManager::get_global_ptr(); in Python, use the cvMgr
+builtin, created by ShowBase.py.
+
+  print cvMgr
+
+    Lists all of the variables in active use: all of the variables
+    whose value has been set by one or more prc files, along with the
+    name of the prc file that defines that value.
+
+  cvMgr.listVariables()
+
+    Lists all of the variables currently known to the config system;
+    that is, all variables for which a ConfigVariable instance has
+    been created at runtime, whether or not its value has been changed
+    from the default.  This may omit variables defined in some unused
+    subsystem (like pandaegg, for instance), and it will omit
+    variables defined by Python code which hasn't yet executed
+    (e.g. variables within defined with a function that hasn't yet
+    been called).
+
+    This will also omit variables deemed to be "dynamic" variables,
+    for instance all of the notify-level-* variables, and variables
+    such as pstats-active-*.  These are omitted simply to keep the
+    list of variable names manageable, since the list of dynamic
+    variable names tends to be very large.  Use
+    cvMgr.listDynamicVariables() if you want to see these variable
+    names.
+
+  cvMgr.listUnusedVariables()
+
+    Lists all of the variables that have been defined by some prc
+    file, but which are not known to the config system (no
+    ConfigVariable instance has yet been created for this variable).
+    These variables may represent misspellings or typos in your prc
+    file, or they may be old variables which are no longer used in the
+    system.  However, they may also be legitimate variables for some
+    subsystem or application which simply has not been loaded; there
+    is no way for Panda to make this distinction.
+
+
+RE-READING PRC FILES
+
+If you modify a prc file at some point after Panda has started, Panda
+will not automatically know that it needs to reload its config files
+and will not therefore automatically recognize your change.  However,
+you can force this to happen by making the following call:
+
+  ConfigPageManager::get_global_ptr()->reload_implicit_pages()
+
+Or, in Python:
+
+  cpMgr.reloadImplicitPages()
+
+This will tell Panda to re-read all of the prc files it found
+automatically at startup and update the variables' values accordingly.
+
+
+RUNTIME PRC FILE MANAGEMENT
+
+In addition to the prc files that are found and loaded automatically
+by Panda at startup, you can load files up at runtime as needed.  The
+functions to manage this are defined in load_prc_file.h:
+
+  ConfigPage *page = load_prc_file("myPage.prc")
+
+  ...
+
+  unload_prc_file(page);
+
+(The above shows the C++ syntax; the corresponding Python code is
+similar, but of course the functions are named loadPrcFile() and
+unloadPrcFile().)
+
+That is to say, you can call load_prc_file() to load up a new prc file
+at any time.  Each file you load is added to a LIFO stack of prc
+files.  If a variable is defined in more than one prc file, the
+topmost file on the stack (i.e. the one most recently loaded) is the
+one that defines the variable's value.
+
+You can call unload_prc_file() at any time to unload a file that you
+have previously loaded.  This removes the file from the stack and
+allows any variables it modified to return to their previous value.
+The single parameter to unload_prc_file() should be the pointer that
+was returned from the corresponding call to load_prc_file().  Once you
+have called unload_prc_file(), the pointer is invalid and should no
+longer be used.  It is an error to call unload_prc_file() twice on the
+same pointer.
+
+The filename given to load_prc_file() may refer to any file that is on
+the standard prc file search path (e.g. $PRC_DIR), as well as on the
+model-path.  It may be a physical file on disk, or a subfile of a
+multifile (and mounted via Panda's virtual file system).
+
+You can see the complete list of prc files that have been loaded into
+the config system at any given time, including files loaded explicitly
+via load_prc_file(), as well as files found in the standard prc file
+search path and loaded implicitly at startup.  Simply use
+ConfigPageManager::write(), e.g. in Python:
+
+  print cpMgr
+
+
+COMPILE-TIME OPTIONS FOR FINDING PRC FILES
+
+As described above in USING THE PRC FILES, Panda's default startup
+behavior is to load all files named *.prc in the directory named by
+the environment variable PRC_DIR.  This is actually a bit of an
+oversimplification.  The complete default behavior is as follows:
+
+(1) If PRC_PATH is set, separate it into a list of directories and
+    make a search path out of it.
+
+(2) If PRC_DIR is set, prepend it onto the search path defined by
+    PRC_PATH, above.
+
+(3) If neither was set, put the compiled-in value for DEFAULT_PRC_DIR,
+    which is usually the install/etc directory, alone on the search
+    path.
+
+(4) Look for all files named *.prc on each directory of the resulting
+    search path, and load them up in reverse search path order, and
+    within each directory, in forward alphabetical order.  This means
+    that directories listed first on the search path override
+    directories listed later, and within a directory, files
+    alphabetically later override files alphabetically earlier.
+
+This describes the default behavior, without any modifications to
+Config.pp.  If you wish, you can further fine-tune each of the above
+steps by defining various Config.pp variables at compile time.  The
+following Config.pp variables may be defined:
+
+#define PRC_PATH_ENVVARS PRC_PATH
+#define PRC_DIR_ENVVARS PRC_DIR
+
+  This names the environment variable(s) to use instead of PRC_PATH
+  and PRC_DIR.  In either case, you may name multiple environment
+  variables separated by a space; each variable is consulted one at a
+  time, in the order named, and the results are concatenated.
+
+  For instance, if you put the following line in your Config.pp file:
+
+  #define PRC_PATH_ENVVARS CFG_PATH ETC_PATH
+
+  Then instead of checking $PRC_PATH in step (1), above, Panda will
+  first check $CFG_PATH, and then $ETC_PATH, and the final search path
+  will be the concatenation of both.
+
+  You can also set either or both of PRC_PATH_ENVVARS or
+  PRC_DIR_ENVVARS to the empty string; this will disable runtime
+  checking of environment variables, and force all prc files to be
+  loaded from the directory named by DEFAULT_PRC_DIR.
+
+#define PRC_PATTERNS *.prc
+
+  This describes the filename patterns that are used to identify prc
+  files in each directory in step(4), above.  The default is *.prc,
+  but you can change this if you have any reason to.  You can specify
+  multiple filename patterns separated by a space.  For instance, if
+  you still have some config files named "Configrc", following an
+  older Panda convention, you can define the following in your
+  Config.pp file:
+
+  #define PRC_PATTERNS *.prc Configrc
+
+  This will cause Panda to recognize files named "Configrc", as well
+  as any file ending in the extension prc, as a legitimate prc file.
+
+#define DEFAULT_PRC_DIR $[INSTALL_DIR]/etc
+
+  This is the directory from which to load prc files if all of the
+  variables named by PRC_PATH_ENVVARS and PRC_DIR_ENVVARS are
+  undefined or empty.
+
+#define DEFAULT_PATHSEP
+
+  This doesn't strictly apply to the config system, since it globally
+  affects search paths throughout Panda.  This specifies the character
+  or characters used to separate the different directory names of a
+  search path, for instance $PRC_PATH.  The default character is ':'
+  on Unix, and ';' on Windows.  If you specify multiple characters,
+  any of them may be used as a separator.
+
+
+EXECUTABLE PRC FILES
+
+One esoteric feature of Panda's config system is the ability to
+automatically execute a standalone program which generates a prc file
+as output.
+
+This feature is not enabled by default.  To enable it, you must define
+the Config.pp variable PRC_EXECUTABLE_PATTERNS before you build Panda.
+This variable is similar to PRC_PATTERNS, described above, except it
+names file names which, when found along the standard prc search path,
+should be taken to be the name of an executable program.  Panda will
+execute each of these programs, in the appropriate order according to
+alphabetical sorting with the regular prc files, and whatever the
+program writes to standard output is taken to be the contents of a prc
+file.
+
+By default the contents of the environment variable
+$PRC_EXECUTABLE_ARGS are passed as arguments to the executable
+program.  You can change this to a different environment variable by
+redefining PRC_EXECUTABLE_ARGS_ENVVAR in your Config.pp (or disable
+this feature by defining this to the empty string).
+
+
+SIGNED PRC FILES
+
+Another esoteric feature of Panda's config system is the ability to
+restrict certain config variables to modification only by a prc file
+that has been provided from an authorized source.  This is primarily
+useful when Panda is to be used for deployment of applications (games,
+etc.) to a client; it has little utility in a fully trusted
+environment.
+
+When this feature is enabled, you can specify an optional trust level
+to each ConfigVariable constructor.  The trust level is an integer
+value, greater than 0 (and <= ConfigFlags::F_trust_level_mask), which
+should be or'ed in with the flags parameter.
+
+A number of random keys must be generated ahead of time and compiled
+into Panda; there must be a different key for each required trust
+level.  Each prc file can then optionally be signed by exactly one of
+the available keys.  When a prc file has been signed by a recognized
+key, Panda assigns the corresponding trust level to that prc file.  An
+unsigned prc file has an implicit trust level of 0.
+
+If a signed prc file is modified in any way after it has been signed,
+its signature will no longer match the contents of the file and its
+trust level drops to 0.  The newly-modified file must be signed again
+to restore its trust level.
+
+When a ConfigVariable is constructed with a nonzero trust level, that
+variable's value may then not be modified by any prc file with a trust
+level lower that the variable's trust level.  If a prc file with an
+insufficient trust level attempts to modify the variable, the new
+value is ignored, and the value from the previous trusted prc file (or
+the variable's default value) is retained.
+
+The default trust level for a ConfigVariable is 0, which means the
+variable can be set by any prc file, signed or unsigned.  To
+explicitly specify a trust level of 0, you should use
+ConfigFlags::F_open.
+
+To specify a ConfigVariable that cannot be set by any prc files at
+all, regardless of trust level, use ConfigFlags::F_closed.
+
+This feature is not enabled by default.  It is somewhat complicated to
+enable this feature, because doing so requres generating one or more
+private/public key pairs, and compiling the public keys into the
+low-level Panda system so that it can recognize signed prc files when
+they are provided, and compiling the private keys into standalone
+executables, one for each private key, that can be used to officially
+sign approved prc files.
+