The XMLRegistry is the central storage for all kinds of variables, settings, preferences, game defaults, etc. As the name states, all the content is stored in XML format, which has some conveniences when accessing, changing and saving the content.
Accessing the Registry
The XMLRegistry plugin (interface defined in iregistry.h) implements some convenient methods to retrieve and save values into the keys. Use the GlobalRegistry() method to retrieve a reference to the XMLRegistry instance.
GlobalRegistry().get(<key>) // returns a string GlobalRegistry().getFloat(<key>) // returns a float GlobalRegistry().getInt(<key>) // returns an int
The above methods try to load the value from the registry and convert them via boost::lexical_cast, if required. If the key is not found in the specified place, an empty value is returned as default ("" or 0.0 or 0).
To save values into the registry, the set methods form the counterparts to the above functions:
GlobalRegistry().set(<key>, <value>) // save the string into <key> GlobalRegistry().setFloat(<key>, <value>) // save the floating point value to <key> GlobalRegistry().setInt(<key>, <value>) // save the integer value to <key>
If the specified key does not exist, it is created and all non-existing parent nodes are created recursively as well. So you don't have to create your key before you save a value into it.
The following is an example of a valid key:
and refers to this node:
<user> <ui> <showAllLightVolumes value="1" /> </ui> </user>
Be sure to always omit the leading slash, so don't use /user/ui/... (see below).
The internal XML tree
As a valid XML document consists of exactly one global parent node, the toplevel node is called <darkradiant>. However, you don't have to specify this toplevel node, as it is added automatically by the XMLRegistry.
So, the key user/ui/showAllLightVolumes is automatically recognised as relative path and becomes /darkradiant/user/ui/showAllLightVolumes before being passed to the libxml functions.
You of course can access the keys with absolute xpaths (/darkradiant/user/ui/showAllLightVolumes for example), but this is not recommended, as the toplevel node is maintained by the registry module only.
Internally, the registry consists of two large subtrees under <darkradiant> and looks like the scetch below. The <user> part of the Registry is imported from the file user.xml and the <game> tree is imported from the doom3.game file in the installation folder.
<darkradiant> <user> -- User preferences go here -- </user> <game> -- Game-specific settings (entity key definitions, etc.) go here -- </game> </darkradiant>
Importing XML files into the Registry
Use the import methods to load a whole file into the registry. You can specify a path, which the content is appended to, but you don't have. By default, the file content is directly inserted as new child of <darkradiant>.
Important note: New files are automatically inserted above all existing nodes in the registry. This is wanted behaviour, because this way it's possible to load all the default values into the XML tree that can be overridden by afterwardly imported nodes of the same name.
This is practiced with the user.xml files: all the default preferences are defined in the install/user.xml file which is imported first. Then DarkRadiant searches for another user.xml copy in the user's settings folder (i.e. "C:\Documents and Settings\bla\Application Data\DarkRadiant\user.xml") and imports its contents, if the file is found. The data is inserted above the other methods, hence the search for a specific key (say "user/ui/showAllLightRadii") will point to the nodes that were imported last. (Hope this is clear, otherwise ask greebo).
The libxml2 library is capable of interpreting the XPath syntax (see reference). Use the findXPath() and deleteXPath() methods to retrieve (or delete) certain paths. The findXPath() method returns an xml::Node structure which in turn provides some methods for adding children, getting attribute values and so on.