diff --git a/doomsday/libdeng2/include/de/core/commandline.h b/doomsday/libdeng2/include/de/core/commandline.h
index 2a9a8752dc..61f3a5f747 100644
--- a/doomsday/libdeng2/include/de/core/commandline.h
+++ b/doomsday/libdeng2/include/de/core/commandline.h
@@ -30,184 +30,185 @@
#include "../String"
#include "../NativePath"
-namespace de
+namespace de {
+
+/**
+ * Stores and provides access to the command line arguments passed
+ * to an application at launch.
+ *
+ * @ingroup core
+ */
+class DENG2_PUBLIC CommandLine
{
+public:
+ /// Tried to access an argument that does not exist. @ingroup errors
+ DENG2_ERROR(OutOfRangeError);
+
+ /// Execution of the command line failed. @ingroup errors
+ DENG2_ERROR(ExecuteError);
+
+public:
+ CommandLine();
+
/**
- * Stores and provides access to the command line arguments passed
- * to an application at launch.
- *
- * @ingroup core
- */
- class DENG2_PUBLIC CommandLine
- {
- public:
- /// Tried to access an argument that does not exist. @ingroup errors
- DENG2_ERROR(OutOfRangeError);
-
- /// Execution of the command line failed. @ingroup errors
- DENG2_ERROR(ExecuteError);
-
- public:
- CommandLine();
-
- /**
- * Constructs a CommandLine out of a list of strings. The argument
- * strings that begin with a @@ character are parsed as response files
- * the rest are used without modification.
- *
- * @param args Arguments to use.
- */
- CommandLine(QStringList const &args);
-
- CommandLine(CommandLine const &other);
-
- virtual ~CommandLine();
-
- /**
- * Returns the native path where the command line was started in.
- * @return Native startup location.
- */
- NativePath startupPath();
-
- /**
- * Returns the number of arguments. This includes the program name, which
- * is the first argument in the list.
- */
- dint count() const;
-
- void clear();
-
- /**
- * Appends a new argument to the list of arguments.
- *
- * @param arg Argument to append.
- */
- void append(String const &arg);
-
- /**
- * Inserts a new argument to the list of arguments at index @a pos.
- *
- * @param pos Index at which the new argument will be at.
- * @param arg Argument to insert.
- */
- void insert(duint pos, String const &arg);
-
- /**
- * Removes an argument by index.
- *
- * @param pos Index of argument to remove.
- */
- void remove(duint pos);
-
- /**
- * Checks whether @a arg is in the arguments. Since the first argument is
- * the program name, it is not included in the search.
- *
- * @param arg Argument to look for. Don't use aliases here.
- * @param count Number of parameters (non-option arguments) that follow
- * the located argument.
- *
- * @see isOption()
- *
- * @return Index of the argument, if found. Otherwise zero.
- */
- dint check(String const &arg, dint count = 0) const;
-
- /**
- * Gets the parameter for an argument.
- *
- * @param arg Argument to look for. Don't use aliases here. Defines
- * aliases will be checked for matches.
- * @param param The parameter is returned here, if found.
- *
- * @return @c true, if parameter was successfully returned.
- * Otherwise @c false, in which case @a param is not modified.
- */
- bool getParameter(String const &arg, String ¶m) const;
-
- /**
- * Determines whether @a arg exists in the list of arguments.
- *
- * @param arg Argument to look for. Don't use aliases here.
- *
- * @return Number of times @a arg is found in the arguments.
- */
- dint has(String const &arg) const;
-
- /**
- * Determines whether an argument is an option, i.e., it begins with a hyphen.
- */
- bool isOption(duint pos) const;
-
- /**
- * Determines whether an argument is an option, i.e., it begins with a hyphen.
- */
- static bool isOption(String const &arg);
-
- String at(duint pos) const;
-
- /**
- * Returns a list of pointers to the arguments. The list contains
- * count() strings and is NULL-terminated.
- */
- char const *const *argv() const;
-
- /**
- * Converts the argument at position @a pos into an absolute native path.
- * Relative paths are converted relative to the directory that was
- * current at the time the CommandLine was created.
- *
- * @param pos Argument index.
- */
- void makeAbsolutePath(duint pos);
-
- /**
- * Reads a native file and parses its contents using parse().
- *
- * @param nativePath File to parse.
- */
- void parseResponseFile(NativePath const &nativePath);
-
- /**
- * Breaks down a single string containing arguments.
- *
- * Examples of behavior:
- * - -cmd "echo ""this is a command""" => [-cmd] [echo "this is a command"]
- * - Hello" My"Friend => [Hello MyFriend]
- * - @@test.rsp [reads contents of test.rsp]
- * - @@\\"Program Files"\\test.rsp [reads contents of "\Program Files\test.rsp"]
- *
- * @param cmdLine String containing the arguments.
- */
- void parse(String const &cmdLine);
-
- /**
- * Defines a new alias for a full argument.
- *
- * @param full The full argument, e.g., "--help"
- * @param alias Alias for the full argument, e.g., "-h"
- */
- void alias(String const &full, String const &alias);
-
- /**
- * @return @c true, iff the two parameters are equivalent according to
- * the abbreviations.
- */
- bool matches(String const &full, String const &fullOrAlias) const;
-
- /**
- * Spawns a new process using the command line. The first argument
- * specifies the file name of the executable. Returns immediately
- * after the process has been started.
- *
- * @return @c true if successful, otherwise @c false.
- */
- bool execute() const;
-
- private:
- struct Instance;
- Instance *d;
- };
-}
+ * Constructs a CommandLine out of a list of strings. The argument
+ * strings that begin with a @@ character are parsed as response files
+ * the rest are used without modification.
+ *
+ * @param args Arguments to use.
+ */
+ CommandLine(QStringList const &args);
+
+ CommandLine(CommandLine const &other);
+
+ virtual ~CommandLine();
+
+ /**
+ * Returns the native path where the command line was started in.
+ * @return Native startup location.
+ */
+ NativePath startupPath();
+
+ /**
+ * Returns the number of arguments. This includes the program name, which
+ * is the first argument in the list.
+ */
+ dint count() const;
+
+ void clear();
+
+ /**
+ * Appends a new argument to the list of arguments.
+ *
+ * @param arg Argument to append.
+ */
+ void append(String const &arg);
+
+ /**
+ * Inserts a new argument to the list of arguments at index @a pos.
+ *
+ * @param pos Index at which the new argument will be at.
+ * @param arg Argument to insert.
+ */
+ void insert(duint pos, String const &arg);
+
+ /**
+ * Removes an argument by index.
+ *
+ * @param pos Index of argument to remove.
+ */
+ void remove(duint pos);
+
+ /**
+ * Checks whether @a arg is in the arguments. Since the first argument is
+ * the program name, it is not included in the search.
+ *
+ * @param arg Argument to look for. Don't use aliases here.
+ * @param count Number of parameters (non-option arguments) that follow
+ * the located argument.
+ *
+ * @see isOption()
+ *
+ * @return Index of the argument, if found. Otherwise zero.
+ */
+ dint check(String const &arg, dint count = 0) const;
+
+ /**
+ * Gets the parameter for an argument.
+ *
+ * @param arg Argument to look for. Don't use aliases here. Defines
+ * aliases will be checked for matches.
+ * @param param The parameter is returned here, if found.
+ *
+ * @return @c true, if parameter was successfully returned.
+ * Otherwise @c false, in which case @a param is not modified.
+ */
+ bool getParameter(String const &arg, String ¶m) const;
+
+ /**
+ * Determines whether @a arg exists in the list of arguments.
+ *
+ * @param arg Argument to look for. Don't use aliases here.
+ *
+ * @return Number of times @a arg is found in the arguments.
+ */
+ dint has(String const &arg) const;
+
+ /**
+ * Determines whether an argument is an option, i.e., it begins with a hyphen.
+ */
+ bool isOption(duint pos) const;
+
+ /**
+ * Determines whether an argument is an option, i.e., it begins with a hyphen.
+ */
+ static bool isOption(String const &arg);
+
+ String at(duint pos) const;
+
+ /**
+ * Returns a list of pointers to the arguments. The list contains
+ * count() strings and is NULL-terminated.
+ */
+ char const *const *argv() const;
+
+ /**
+ * Converts the argument at position @a pos into an absolute native path.
+ * Relative paths are converted relative to the directory that was
+ * current at the time the CommandLine was created.
+ *
+ * @param pos Argument index.
+ */
+ void makeAbsolutePath(duint pos);
+
+ /**
+ * Reads a native file and parses its contents using parse().
+ *
+ * @param nativePath File to parse.
+ */
+ void parseResponseFile(NativePath const &nativePath);
+
+ /**
+ * Breaks down a single string containing arguments.
+ *
+ * Examples of behavior:
+ * - -cmd "echo ""this is a command""" => [-cmd] [echo "this is a command"]
+ * - Hello" My"Friend => [Hello MyFriend]
+ * - @@test.rsp [reads contents of test.rsp]
+ * - @@\\"Program Files"\\test.rsp [reads contents of "\Program Files\test.rsp"]
+ *
+ * @param cmdLine String containing the arguments.
+ */
+ void parse(String const &cmdLine);
+
+ /**
+ * Defines a new alias for a full argument.
+ *
+ * @param full The full argument, e.g., "--help"
+ * @param alias Alias for the full argument, e.g., "-h"
+ */
+ void alias(String const &full, String const &alias);
+
+ /**
+ * @return @c true, iff the two parameters are equivalent according to
+ * the abbreviations.
+ */
+ bool matches(String const &full, String const &fullOrAlias) const;
+
+ /**
+ * Spawns a new process using the command line. The first argument
+ * specifies the file name of the executable. Returns immediately
+ * after the process has been started.
+ *
+ * @return @c true if successful, otherwise @c false.
+ */
+ bool execute() const;
+
+private:
+ struct Instance;
+ Instance *d;
+};
+
+} // namespace de
#endif /* LIBDENG2_COMMANDLINE_H */
diff --git a/doomsday/libdeng2/include/de/core/config.h b/doomsday/libdeng2/include/de/core/config.h
index 3d827825c0..a9978bc30d 100644
--- a/doomsday/libdeng2/include/de/core/config.h
+++ b/doomsday/libdeng2/include/de/core/config.h
@@ -24,88 +24,89 @@
#include "../String"
#include "../Path"
-namespace de
+namespace de {
+
+class ArrayValue;
+
+/**
+ * Stores the configuration of everything. The application owns a Config.
+ * The default configuration is produced by executing the .de scripts
+ * in the config directories. The resulting namespace is serialized for
+ * storage, and is restored from the serialized version directly before the
+ * config scripts are run.
+ *
+ * The version of the engine is stored in the serialized config namespace.
+ * This is for actions needed when upgrading: the config script can check
+ * the previous version and apply changes accordingly.
+ */
+class DENG2_PUBLIC Config
{
- class ArrayValue;
+public:
+ /// Attempted to get the value of a variable while expecting the wrong type. @ingroup errors
+ DENG2_ERROR(ValueTypeError);
+public:
/**
- * Stores the configuration of everything. The application owns a Config.
- * The default configuration is produced by executing the .de scripts
- * in the config directories. The resulting namespace is serialized for
- * storage, and is restored from the serialized version directly before the
- * config scripts are run.
+ * Constructs a new configuration.
*
- * The version of the engine is stored in the serialized config namespace.
- * This is for actions needed when upgrading: the config script can check
- * the previous version and apply changes accordingly.
+ * @param path Name of the configuration file to read.
*/
- class DENG2_PUBLIC Config
- {
- public:
- /// Attempted to get the value of a variable while expecting the wrong type. @ingroup errors
- DENG2_ERROR(ValueTypeError);
-
- public:
- /**
- * Constructs a new configuration.
- *
- * @param path Name of the configuration file to read.
- */
- Config(Path const &path);
-
- /**
- * Destructor. The configuration is automatically saved.
- */
- virtual ~Config();
-
- /// Read configuration from files.
- void read();
-
- /// Writes the configuration to /home.
- void write();
-
- /// Returns the value of @a name as a Value.
- Value &get(String const &name);
-
- /// Returns the value of @a name as an integer.
- dint geti(String const &name);
-
- /// Returns the value of @a name as a boolean.
- bool getb(String const &name);
-
- /// Returns the value of @a name as an unsigned integer.
- duint getui(String const &name);
-
- /// Returns the value of @a name as a double-precision floating point number.
- ddouble getd(String const &name);
-
- /// Returns the value of @a name as a string.
- String gets(String const &name);
-
- /// Returns the value of @a name as an array value. An exception is thrown
- /// if the variable does not have an array value.
- ArrayValue &geta(String const &name);
-
- template
- ValueType &getAs(String const &name) {
- ValueType *v = dynamic_cast(&get(name));
- if(!v)
- {
- throw ValueTypeError("Config::getAs", String("Cannot cast to expected type (") +
- DENG2_TYPE_NAME(ValueType) + ")");
- }
- return *v;
+ Config(Path const &path);
+
+ /**
+ * Destructor. The configuration is automatically saved.
+ */
+ virtual ~Config();
+
+ /// Read configuration from files.
+ void read();
+
+ /// Writes the configuration to /home.
+ void write();
+
+ /// Returns the value of @a name as a Value.
+ Value &get(String const &name);
+
+ /// Returns the value of @a name as an integer.
+ dint geti(String const &name);
+
+ /// Returns the value of @a name as a boolean.
+ bool getb(String const &name);
+
+ /// Returns the value of @a name as an unsigned integer.
+ duint getui(String const &name);
+
+ /// Returns the value of @a name as a double-precision floating point number.
+ ddouble getd(String const &name);
+
+ /// Returns the value of @a name as a string.
+ String gets(String const &name);
+
+ /// Returns the value of @a name as an array value. An exception is thrown
+ /// if the variable does not have an array value.
+ ArrayValue &geta(String const &name);
+
+ template
+ ValueType &getAs(String const &name) {
+ ValueType *v = dynamic_cast(&get(name));
+ if(!v)
+ {
+ throw ValueTypeError("Config::getAs", String("Cannot cast to expected type (") +
+ DENG2_TYPE_NAME(ValueType) + ")");
}
-
- /**
- * Returns the configuration namespace.
- */
- Record &names();
-
- private:
- struct Instance;
- Instance *d;
- };
-}
+ return *v;
+ }
+
+ /**
+ * Returns the configuration namespace.
+ */
+ Record &names();
+
+private:
+ struct Instance;
+ Instance *d;
+};
+
+} // namespace de
#endif /* LIBDENG2_CONFIG_H */
diff --git a/doomsday/libdeng2/include/de/core/library.h b/doomsday/libdeng2/include/de/core/library.h
index cc54852c53..2a22c1f0f1 100644
--- a/doomsday/libdeng2/include/de/core/library.h
+++ b/doomsday/libdeng2/include/de/core/library.h
@@ -32,188 +32,189 @@
*/
#define DENG2_SYMBOL(Name) symbol(#Name)
-namespace de
+namespace de {
+
+class Audio;
+class Map;
+class Object;
+class User;
+class World;
+
+/**
+ * The Library class allows loading shared library files
+ * (DLL/so/bundle/dylib) and looks up exported symbols in the libraries.
+ *
+ * Library type identifiers;
+ * - library/generic
: A shared library with no special function.
+ * - deng-plugin/generic
: Generic libdeng2 plugin. Loaded always.
+ * - deng-plugin/game
: The game plugin. Only one of these can be loaded.
+ * - deng-plugin/audio
: Audio driver. Optional. Loaded on demand by
+ * the audio subsystem.
+ *
+ * @ingroup core
+ */
+class DENG2_PUBLIC Library
{
- class Audio;
- class Map;
- class Object;
- class User;
- class World;
-
- /**
- * The Library class allows loading shared library files
- * (DLL/so/bundle/dylib) and looks up exported symbols in the libraries.
+public:
+ /// Loading the shared library failed. @ingroup errors
+ DENG2_ERROR(LoadError);
+
+ /// A symbol was not found. @ingroup errors
+ DENG2_ERROR(SymbolMissingError);
+
+ /// Default type identifier.
+ static char const *DEFAULT_TYPE;
+
+ // Common function profiles.
+ /**
+ * Queries the plugin for a type identifier string. If this function is not
+ * defined, the identifier defaults to DEFAULT_TYPE.
*
- * Library type identifiers;
- * - library/generic
: A shared library with no special function.
- * - deng-plugin/generic
: Generic libdeng2 plugin. Loaded always.
- * - deng-plugin/game
: The game plugin. Only one of these can be loaded.
- * - deng-plugin/audio
: Audio driver. Optional. Loaded on demand by
- * the audio subsystem.
+ * @return Type identifier string.
+ */
+ typedef char const *(*deng_LibraryType)(void);
+
+ /**
+ * Passes Doomsda'ys public APIs to the library. Called automatically by
+ * the engine when loading libraries.
+ */
+ typedef void (*deng_API)(int, void *);
+
+ /**
+ * Performs any one-time initialization necessary for the usage of the plugin.
+ * If this symbol is exported from a shared library, it gets called automatically
+ * when the library is loaded. Note that this is called before deng_API(), so it
+ * should be used exclusively for setting up the plugin's internal state.
+ */
+ typedef void (*deng_InitializePlugin)(void);
+
+ /**
+ * Frees resources reserved by the plugin. If this symbol is exported from a
+ * shared library, it gets called automatically when the library is unloaded.
+ */
+ typedef void (*deng_ShutdownPlugin)(void);
+
+ /**
+ * Constructs a new instance of an audio subsystem.
*
- * @ingroup core
- */
- class DENG2_PUBLIC Library
- {
- public:
- /// Loading the shared library failed. @ingroup errors
- DENG2_ERROR(LoadError);
-
- /// A symbol was not found. @ingroup errors
- DENG2_ERROR(SymbolMissingError);
-
- /// Default type identifier.
- static char const *DEFAULT_TYPE;
-
- // Common function profiles.
- /**
- * Queries the plugin for a type identifier string. If this function is not
- * defined, the identifier defaults to DEFAULT_TYPE.
- *
- * @return Type identifier string.
- */
- typedef char const *(*deng_LibraryType)(void);
+ * @return Audio subsystem.
+ */
+ typedef Audio *(*deng_NewAudio)(void);
- /**
- * Passes Doomsda'ys public APIs to the library. Called automatically by
- * the engine when loading libraries.
- */
- typedef void (*deng_API)(int, void *);
-
- /**
- * Performs any one-time initialization necessary for the usage of the plugin.
- * If this symbol is exported from a shared library, it gets called automatically
- * when the library is loaded. Note that this is called before deng_API(), so it
- * should be used exclusively for setting up the plugin's internal state.
- */
- typedef void (*deng_InitializePlugin)(void);
-
- /**
- * Frees resources reserved by the plugin. If this symbol is exported from a
- * shared library, it gets called automatically when the library is unloaded.
- */
- typedef void (*deng_ShutdownPlugin)(void);
-
- /**
- * Constructs a new instance of an audio subsystem.
- *
- * @return Audio subsystem.
- */
- typedef Audio *(*deng_NewAudio)(void);
-
- /**
- * Constructs a new game world.
- */
- typedef World *(*deng_NewWorld)(void);
-
- /**
- * Constructs a new game map.
- */
- typedef Map *(*deng_NewMap)();
-
- /**
- * Constructs a new object.
- */
- typedef Object *(*deng_NewObject)(void);
-
- /**
- * Constructs a new user.
- */
- typedef User *(*deng_NewUser)(void);
-
- typedef dint (*deng_GetInteger)(dint id);
- typedef char const *(*deng_GetString)(dint id);
- typedef void *(*deng_GetAddress)(dint id);
- typedef void (*deng_Ticker)(ddouble tickLength);
-
- public:
- /**
- * Constructs a new Library by loading a native shared library.
- *
- * @param nativePath Path of the shared library to load.
- */
- Library(NativePath const &nativePath);
-
- /**
- * Unloads the shared library.
- */
- virtual ~Library();
+ /**
+ * Constructs a new game world.
+ */
+ typedef World *(*deng_NewWorld)(void);
- /**
- * Returns the type identifier of the library. This affects how
- * libdeng2 will treat the library. The type is determined
- * automatically when the library is first loaded, and can then be
- * queried at any time even after the library has been unloaded.
- */
- String const &type() const;
+ /**
+ * Constructs a new game map.
+ */
+ typedef Map *(*deng_NewMap)();
- enum SymbolLookupMode {
- RequiredSymbol, ///< Symbol must be exported.
- OptionalSymbol ///< Symbol can be missing.
- };
+ /**
+ * Constructs a new object.
+ */
+ typedef Object *(*deng_NewObject)(void);
- /**
- * Gets the address of an exported symbol. Throws an exception if a required
- * symbol is not found.
- *
- * @param name Name of the exported symbol.
- * @param lookup Lookup mode (required or optional).
- *
- * @return A pointer to the symbol. Returns @c NULL if an optional symbol is
- * not found.
- */
- void *address(String const &name, SymbolLookupMode lookup = RequiredSymbol);
+ /**
+ * Constructs a new user.
+ */
+ typedef User *(*deng_NewUser)(void);
- /**
- * Checks if the library exports a specific symbol.
- * @param name Name of the exported symbol.
- * @return @c true if the symbol is exported, @c false if not.
- */
- bool hasSymbol(String const &name) const;
+ typedef dint (*deng_GetInteger)(dint id);
+ typedef char const *(*deng_GetString)(dint id);
+ typedef void *(*deng_GetAddress)(dint id);
+ typedef void (*deng_Ticker)(ddouble tickLength);
- /**
- * Gets the address of a symbol. Throws an exception if a required symbol
- * is not found.
- *
- * @param name Name of the symbol.
- * @param lookup Symbol lookup mode (required or optional).
- *
- * @return Pointer to the symbol as type @a Type.
- */
- template
- Type symbol(String const &name, SymbolLookupMode lookup = RequiredSymbol) {
- /**
- * @note Casting to a pointer-to-function type: see
- * http://www.trilithium.com/johan/2004/12/problem-with-dlsym/
- */
- // This is not 100% portable to all possible memory architectures; thus:
- DENG2_ASSERT(sizeof(void *) == sizeof(Type));
-
- union { void *original; Type target; } forcedCast;
- forcedCast.original = address(name, lookup);
- return forcedCast.target;
- }
+public:
+ /**
+ * Constructs a new Library by loading a native shared library.
+ *
+ * @param nativePath Path of the shared library to load.
+ */
+ Library(NativePath const &nativePath);
+
+ /**
+ * Unloads the shared library.
+ */
+ virtual ~Library();
+
+ /**
+ * Returns the type identifier of the library. This affects how
+ * libdeng2 will treat the library. The type is determined
+ * automatically when the library is first loaded, and can then be
+ * queried at any time even after the library has been unloaded.
+ */
+ String const &type() const;
+ enum SymbolLookupMode {
+ RequiredSymbol, ///< Symbol must be exported.
+ OptionalSymbol ///< Symbol can be missing.
+ };
+
+ /**
+ * Gets the address of an exported symbol. Throws an exception if a required
+ * symbol is not found.
+ *
+ * @param name Name of the exported symbol.
+ * @param lookup Lookup mode (required or optional).
+ *
+ * @return A pointer to the symbol. Returns @c NULL if an optional symbol is
+ * not found.
+ */
+ void *address(String const &name, SymbolLookupMode lookup = RequiredSymbol);
+
+ /**
+ * Checks if the library exports a specific symbol.
+ * @param name Name of the exported symbol.
+ * @return @c true if the symbol is exported, @c false if not.
+ */
+ bool hasSymbol(String const &name) const;
+
+ /**
+ * Gets the address of a symbol. Throws an exception if a required symbol
+ * is not found.
+ *
+ * @param name Name of the symbol.
+ * @param lookup Symbol lookup mode (required or optional).
+ *
+ * @return Pointer to the symbol as type @a Type.
+ */
+ template
+ Type symbol(String const &name, SymbolLookupMode lookup = RequiredSymbol) {
/**
- * Utility template for acquiring pointers to symbols. Throws an exception
- * if a required symbol is not found.
- *
- * @param ptr Pointer that will be set to point to the symbol's address.
- * @param name Name of the symbol whose address to get.
- * @param lookup Symbol lookup mode (required or optional).
- *
- * @return @c true, if the symbol was found. Otherwise @c false.
+ * @note Casting to a pointer-to-function type: see
+ * http://www.trilithium.com/johan/2004/12/problem-with-dlsym/
*/
- template
- bool setSymbolPtr(Type &ptr, String const &name, SymbolLookupMode lookup = RequiredSymbol) {
- ptr = symbol(name, lookup);
- return ptr != 0;
- }
-
- private:
- struct Instance;
- Instance *d;
- };
-}
+ // This is not 100% portable to all possible memory architectures; thus:
+ DENG2_ASSERT(sizeof(void *) == sizeof(Type));
+
+ union { void *original; Type target; } forcedCast;
+ forcedCast.original = address(name, lookup);
+ return forcedCast.target;
+ }
+
+ /**
+ * Utility template for acquiring pointers to symbols. Throws an exception
+ * if a required symbol is not found.
+ *
+ * @param ptr Pointer that will be set to point to the symbol's address.
+ * @param name Name of the symbol whose address to get.
+ * @param lookup Symbol lookup mode (required or optional).
+ *
+ * @return @c true, if the symbol was found. Otherwise @c false.
+ */
+ template
+ bool setSymbolPtr(Type &ptr, String const &name, SymbolLookupMode lookup = RequiredSymbol) {
+ ptr = symbol(name, lookup);
+ return ptr != 0;
+ }
+
+private:
+ struct Instance;
+ Instance *d;
+};
+
+} // namespace de
#endif /* LIBDENG2_LIBRARY_H */
diff --git a/doomsday/libdeng2/include/de/data/archive.h b/doomsday/libdeng2/include/de/data/archive.h
index 0036b68687..706603e788 100644
--- a/doomsday/libdeng2/include/de/data/archive.h
+++ b/doomsday/libdeng2/include/de/data/archive.h
@@ -30,297 +30,298 @@
#include
-namespace de
+namespace de {
+
+class IBlock;
+class Block;
+
+/**
+ * Collection of named memory blocks stored inside a byte array.
+ *
+ * An archive consists of a collection of Block instances that are
+ * identified using a path tree structure. Blocks can be added and removed
+ * at any time.
+ *
+ * Archive is merely IWritable instead of ISerializable because of its
+ * memory management model. The basic assumption is that even though the
+ * archive is kept in serialized form, individual entries can still be
+ * accessed without processing the entire serialization. Therefore, Archive
+ * only operates on existing, serialized archives that live in externally
+ * owned byte arrays; Archive does not take ownership of the source data.
+ * This also means that read-only access to very large byte arrays can be
+ * done without loading all the source data into memory (e.g., Archive
+ * that reads from a large NativeFile).
+ *
+ * It is also assumed that accessing the source data and extracting a
+ * particular entry is potentially a slow operation: when individual
+ * entries are read from the source, the entries are cached in memory so
+ * that subsequent access is fast.
+ *
+ * An Archive instance expects that the source byte array is never changed
+ * by third parties while it is the source of the Archive.
+ *
+ * It is possible to detach an Archive instance from its source byte array
+ * by calling @c cache(DetachFromSource). This forces all entries to be
+ * copied to Archive-owned memory (in original serialized form).
+ *
+ * @see ArchiveFeed, ArchiveEntryFile
+ *
+ * @ingroup data
+ */
+class DENG2_PUBLIC Archive : public IWritable
{
- class IBlock;
- class Block;
-
+public:
+ /// Base class for format-related errors. @ingroup errors
+ DENG2_ERROR(FormatError);
+
+ /// Provided path was not valid. @ingroup errors
+ DENG2_ERROR(InvalidPathError);
+
+ /// The requested entry does not exist in the archive. @ingroup errors
+ DENG2_ERROR(NotFoundError);
+
+ /// There is an error related to content processing. @ingroup errors
+ DENG2_ERROR(ContentError);
+
+ typedef std::set Names; // alphabetical order
+
+public:
+ /**
+ * Constructs an empty Archive.
+ */
+ Archive();
+
+ /**
+ * Constructs a new Archive instance. The content index contained in
+ * @a data is read during construction.
+ *
+ * @param data Data of the source archive. No copy of the
+ * data is made, so the caller must make sure the
+ * byte array remains in existence for the lifetime
+ * of the Archive instance.
+ */
+ Archive(IByteArray const &data);
+
+ virtual ~Archive();
+
+ /**
+ * Returns the source byte array. @c NULL, if the archive was
+ * constructed without a source (as empty) or has been detached from
+ * its original source.
+ */
+ IByteArray const *source() const;
+
+ enum CacheAttachment {
+ RemainAttachedToSource = 0,
+ DetachFromSource = 1
+ };
+
+ /**
+ * Loads a copy of the serialized data into memory for all the entries that
+ * don't already have deserialized data stored.
+ *
+ * @param attach If DetachFromSource, the archive becomes a standalone
+ * archive that no longer needs the source byte array to
+ * remain in existence.
+ */
+ void cache(CacheAttachment attach = DetachFromSource);
+
+ /**
+ * Determines whether the archive contains an entry (not a folder).
+ *
+ * @param path Path of the entry.
+ *
+ * @return @c true or @c false.
+ */
+ bool hasEntry(Path const &path) const;
+
+ /**
+ * List the files in a specific folder of the archive.
+ *
+ * @param folder Folder path to look in. By default looks in the root.
+ * @param names Entry names collected in a set. The names are relative to a
+ * @a folder and are in alphabetical order.
+ *
+ * @return Number of names returned in @a names.
+ */
+ dint listFiles(Names &names, Path const &folder = Path()) const;
+
+ /**
+ * List the folders in a specific folder of the archive.
+ *
+ * @param folder Folder path to look in. By default looks in the root.
+ * @param names Folder entry names collected in a set. The names are
+ * relative to @a folder and are in alphabetical order.
+ *
+ * @return Number of names returned in @a names.
+ */
+ dint listFolders(Names &names, Path const &folder = Path()) const;
+
+ /**
+ * Returns information about the specified path.
+ *
+ * @param path Path of the entry within the archive.
+ *
+ * @return Type, size, and other metadata about the entry.
+ */
+ File::Status entryStatus(Path const &path) const;
+
/**
- * Collection of named memory blocks stored inside a byte array.
+ * Returns the deserialized data of an entry for read-only access. The
+ * data is deserialized and cached if a cached copy doesn't already
+ * exist.
*
- * An archive consists of a collection of Block instances that are
- * identified using a path tree structure. Blocks can be added and removed
- * at any time.
+ * This method operates on the Archive in immutable mode: the user is
+ * not expected to modify the contents of the returned Block, and the
+ * existing serialized data of the entry can be used as-is when the
+ * archive is written.
*
- * Archive is merely IWritable instead of ISerializable because of its
- * memory management model. The basic assumption is that even though the
- * archive is kept in serialized form, individual entries can still be
- * accessed without processing the entire serialization. Therefore, Archive
- * only operates on existing, serialized archives that live in externally
- * owned byte arrays; Archive does not take ownership of the source data.
- * This also means that read-only access to very large byte arrays can be
- * done without loading all the source data into memory (e.g., Archive
- * that reads from a large NativeFile).
+ * @param path Entry path. The entry must already exist in the archive.
*
- * It is also assumed that accessing the source data and extracting a
- * particular entry is potentially a slow operation: when individual
- * entries are read from the source, the entries are cached in memory so
- * that subsequent access is fast.
+ * @return Immutable contents of the entry.
+ */
+ Block const &entryBlock(Path const &path) const;
+
+ inline Block const &constEntryBlock(Path const &path) const {
+ return entryBlock(path);
+ }
+
+ /**
+ * Returns the deserialized data of an entry for read and write access.
+ * The data is deserialized and cached if a cached copy doesn't already
+ * exist.
*
- * An Archive instance expects that the source byte array is never changed
- * by third parties while it is the source of the Archive.
+ * The user is allowed to make changes to the returned block. The
+ * entry's data is automatically marked for re-serialization in case
+ * the archive is written.
*
- * It is possible to detach an Archive instance from its source byte array
- * by calling @c cache(DetachFromSource). This forces all entries to be
- * copied to Archive-owned memory (in original serialized form).
+ * @param path Entry path. If doesn't exist, a new entry will be added.
*
- * @see ArchiveFeed, ArchiveEntryFile
+ * @return Modifiable contents of the entry.
+ */
+ Block &entryBlock(Path const &path);
+
+ /**
+ * Adds an entry to the archive. The entry will not be committed to the
+ * source, but instead remains as-is in memory.
+ *
+ * @param path Path of the entry within the archive.
+ * @param data Data of the entry.
+ */
+ void add(Path const &path, IByteArray const &data);
+
+ /**
+ * Removes an entry from the archive. If there is deserialized data for
+ * the entry in memory, it will be deleted.
*
- * @ingroup data
+ * @param path Path of the entry.
+ */
+ void remove(Path const &path);
+
+ /**
+ * Clears the index of the archive. All entries are deleted.
+ */
+ void clear();
+
+ /**
+ * Determines if the archive has been modified.
+ */
+ bool modified() const;
+
+ /**
+ * Writes the archive to a Writer. Deserialized entries are
+ * re-serialized just-in-time before writing if they have been
+ * modified.
+ *
+ * @note If overwriting the source array, be sure to either first write
+ * to a temporary array and then replace the source, or alternatively
+ * detach the source from the archive beforehand. Otherwise the
+ * unchanged entries may become corrupted as they are reused from their
+ * old location in the source, which may have been already overwritten.
+ *
+ * @param to Where to write.
+ */
+ virtual void operator >> (Writer &to) const = 0;
+
+protected:
+ /*
+ * Interface for derived classes:
*/
- class DENG2_PUBLIC Archive : public IWritable
+ /// Base class for archive entries.
+ struct Entry : public PathTree::Node
{
- public:
- /// Base class for format-related errors. @ingroup errors
- DENG2_ERROR(FormatError);
-
- /// Provided path was not valid. @ingroup errors
- DENG2_ERROR(InvalidPathError);
-
- /// The requested entry does not exist in the archive. @ingroup errors
- DENG2_ERROR(NotFoundError);
-
- /// There is an error related to content processing. @ingroup errors
- DENG2_ERROR(ContentError);
-
- typedef std::set Names; // alphabetical order
-
- public:
- /**
- * Constructs an empty Archive.
- */
- Archive();
-
- /**
- * Constructs a new Archive instance. The content index contained in
- * @a data is read during construction.
- *
- * @param data Data of the source archive. No copy of the
- * data is made, so the caller must make sure the
- * byte array remains in existence for the lifetime
- * of the Archive instance.
- */
- Archive(IByteArray const &data);
-
- virtual ~Archive();
-
- /**
- * Returns the source byte array. @c NULL, if the archive was
- * constructed without a source (as empty) or has been detached from
- * its original source.
- */
- IByteArray const *source() const;
-
- enum CacheAttachment {
- RemainAttachedToSource = 0,
- DetachFromSource = 1
- };
-
- /**
- * Loads a copy of the serialized data into memory for all the entries that
- * don't already have deserialized data stored.
- *
- * @param attach If DetachFromSource, the archive becomes a standalone
- * archive that no longer needs the source byte array to
- * remain in existence.
- */
- void cache(CacheAttachment attach = DetachFromSource);
-
- /**
- * Determines whether the archive contains an entry (not a folder).
- *
- * @param path Path of the entry.
- *
- * @return @c true or @c false.
- */
- bool hasEntry(Path const &path) const;
-
- /**
- * List the files in a specific folder of the archive.
- *
- * @param folder Folder path to look in. By default looks in the root.
- * @param names Entry names collected in a set. The names are relative to a
- * @a folder and are in alphabetical order.
- *
- * @return Number of names returned in @a names.
- */
- dint listFiles(Names &names, Path const &folder = Path()) const;
-
- /**
- * List the folders in a specific folder of the archive.
- *
- * @param folder Folder path to look in. By default looks in the root.
- * @param names Folder entry names collected in a set. The names are
- * relative to @a folder and are in alphabetical order.
- *
- * @return Number of names returned in @a names.
- */
- dint listFolders(Names &names, Path const &folder = Path()) const;
-
- /**
- * Returns information about the specified path.
- *
- * @param path Path of the entry within the archive.
- *
- * @return Type, size, and other metadata about the entry.
- */
- File::Status entryStatus(Path const &path) const;
-
- /**
- * Returns the deserialized data of an entry for read-only access. The
- * data is deserialized and cached if a cached copy doesn't already
- * exist.
- *
- * This method operates on the Archive in immutable mode: the user is
- * not expected to modify the contents of the returned Block, and the
- * existing serialized data of the entry can be used as-is when the
- * archive is written.
- *
- * @param path Entry path. The entry must already exist in the archive.
- *
- * @return Immutable contents of the entry.
- */
- Block const &entryBlock(Path const &path) const;
-
- inline Block const &constEntryBlock(Path const &path) const {
- return entryBlock(path);
- }
+ dsize offset; ///< Offset from the start of the source array.
+ dsize size; ///< Deserialized size.
+ dsize sizeInArchive; ///< Size within the archive (serialized).
+ Time modifiedAt; ///< Latest modification timestamp.
+ bool maybeChanged; ///< @c true, if the data must be re-serialized when writing.
+
+ /// Deserialized data. Can be @c NULL. Entry has ownership.
+ Block *data;
+
+ /// Cached copy of the serialized data. Can be @c NULL. Entry has ownership.
+ Block mutable *dataInArchive;
- /**
- * Returns the deserialized data of an entry for read and write access.
- * The data is deserialized and cached if a cached copy doesn't already
- * exist.
- *
- * The user is allowed to make changes to the returned block. The
- * entry's data is automatically marked for re-serialization in case
- * the archive is written.
- *
- * @param path Entry path. If doesn't exist, a new entry will be added.
- *
- * @return Modifiable contents of the entry.
- */
- Block &entryBlock(Path const &path);
-
- /**
- * Adds an entry to the archive. The entry will not be committed to the
- * source, but instead remains as-is in memory.
- *
- * @param path Path of the entry within the archive.
- * @param data Data of the entry.
- */
- void add(Path const &path, IByteArray const &data);
-
- /**
- * Removes an entry from the archive. If there is deserialized data for
- * the entry in memory, it will be deleted.
- *
- * @param path Path of the entry.
- */
- void remove(Path const &path);
-
- /**
- * Clears the index of the archive. All entries are deleted.
- */
- void clear();
-
- /**
- * Determines if the archive has been modified.
- */
- bool modified() const;
-
- /**
- * Writes the archive to a Writer. Deserialized entries are
- * re-serialized just-in-time before writing if they have been
- * modified.
- *
- * @note If overwriting the source array, be sure to either first write
- * to a temporary array and then replace the source, or alternatively
- * detach the source from the archive beforehand. Otherwise the
- * unchanged entries may become corrupted as they are reused from their
- * old location in the source, which may have been already overwritten.
- *
- * @param to Where to write.
- */
- virtual void operator >> (Writer &to) const = 0;
-
- protected:
- /*
- * Interface for derived classes:
- */
- /// Base class for archive entries.
- struct Entry : public PathTree::Node
+ Entry(PathTree::NodeArgs const &args) : Node(args),
+ offset(0),
+ size(0),
+ sizeInArchive(0),
+ maybeChanged(false),
+ data(0),
+ dataInArchive(0)
+ {}
+
+ virtual ~Entry()
{
- dsize offset; ///< Offset from the start of the source array.
- dsize size; ///< Deserialized size.
- dsize sizeInArchive; ///< Size within the archive (serialized).
- Time modifiedAt; ///< Latest modification timestamp.
- bool maybeChanged; ///< @c true, if the data must be re-serialized when writing.
-
- /// Deserialized data. Can be @c NULL. Entry has ownership.
- Block *data;
-
- /// Cached copy of the serialized data. Can be @c NULL. Entry has ownership.
- Block mutable *dataInArchive;
-
- Entry(PathTree::NodeArgs const &args) : Node(args),
- offset(0),
- size(0),
- sizeInArchive(0),
- maybeChanged(false),
- data(0),
- dataInArchive(0)
- {}
-
- virtual ~Entry()
- {
- // Entry has ownership of the cached data.
- delete data;
- delete dataInArchive;
- }
- };
-
- /**
- * Sets the index used by the Archive. A concrete subclass must call
- * this in their constructor; Archive does not create an index on its
- * own.
- *
- * @param tree PathTree with entries of suitable type. Ownership given to Archive.
- */
- void setIndex(PathTree *tree);
-
- /**
- * Reads an entry from the source archive. The implementation of this
- * method is expected to cache the read data of the entry in its
- * original, serialized format in Entry::dataInArchive.
- *
- * @param entry Entry that is being read.
- * @param path Path of the entry within the archive.
- * @param data Data is written here.
- */
- virtual void readFromSource(Entry const &entry, Path const &path, IBlock &data) const = 0;
-
- /**
- * Inserts an entry into the archive's index. If the path already
- * exists in the index, the old entry is deleted first.
- *
- * @param path Path of the entry.
- *
- * @return Inserted entry.
- */
- Entry &insertEntry(Path const &path);
-
- /**
- * Returns the full entry index so that derived classes can iterate the
- * entries.
- *
- * @return Entry index.
- */
- PathTree const &index() const;
-
- private:
- struct Instance;
- Instance *d;
+ // Entry has ownership of the cached data.
+ delete data;
+ delete dataInArchive;
+ }
};
-}
+
+ /**
+ * Sets the index used by the Archive. A concrete subclass must call
+ * this in their constructor; Archive does not create an index on its
+ * own.
+ *
+ * @param tree PathTree with entries of suitable type. Ownership given to Archive.
+ */
+ void setIndex(PathTree *tree);
+
+ /**
+ * Reads an entry from the source archive. The implementation of this
+ * method is expected to cache the read data of the entry in its
+ * original, serialized format in Entry::dataInArchive.
+ *
+ * @param entry Entry that is being read.
+ * @param path Path of the entry within the archive.
+ * @param data Data is written here.
+ */
+ virtual void readFromSource(Entry const &entry, Path const &path, IBlock &data) const = 0;
+
+ /**
+ * Inserts an entry into the archive's index. If the path already
+ * exists in the index, the old entry is deleted first.
+ *
+ * @param path Path of the entry.
+ *
+ * @return Inserted entry.
+ */
+ Entry &insertEntry(Path const &path);
+
+ /**
+ * Returns the full entry index so that derived classes can iterate the
+ * entries.
+ *
+ * @return Entry index.
+ */
+ PathTree const &index() const;
+
+private:
+ struct Instance;
+ Instance *d;
+};
+
+} // namespace de
#endif /* LIBDENG2_ARCHIVE_H */
diff --git a/doomsday/libdeng2/include/de/data/counted.h b/doomsday/libdeng2/include/de/data/counted.h
index 74edd71183..c607bf9174 100644
--- a/doomsday/libdeng2/include/de/data/counted.h
+++ b/doomsday/libdeng2/include/de/data/counted.h
@@ -22,64 +22,64 @@
#include "../libdeng2.h"
-namespace de
+namespace de {
+/**
+ * Reference-counted object. Gets destroyed when its reference counter
+ * hits zero.
+ *
+ * @ingroup data
+ */
+class DENG2_PUBLIC Counted
{
+public:
/**
- * Reference-counted object. Gets destroyed when its reference counter
- * hits zero.
+ * New counted objects have a reference count of 1 -- it is assumed
+ * that whoever constructs the object holds on to one reference.
+ */
+ Counted();
+
+ /**
+ * Acquires a reference to the reference-counted object. Use the
+ * template to get the correct type of pointer from a derived class.
+ */
+ template
+ Type *ref() {
+ addRef();
+ return static_cast(this);
+ }
+
+ /**
+ * Releases a reference that was acquired earlier with ref(). The
+ * object destroys itself when the reference counter hits zero.
+ */
+ void release();
+
+protected:
+ /**
+ * Modifies the reference counter. If the reference count is reduced to
+ * zero, the caller is responsible for making sure the object gets
+ * deleted.
*
- * @ingroup data
+ * @param count Added to the reference counter.
*/
- class DENG2_PUBLIC Counted
- {
- public:
- /**
- * New counted objects have a reference count of 1 -- it is assumed
- * that whoever constructs the object holds on to one reference.
- */
- Counted();
-
- /**
- * Acquires a reference to the reference-counted object. Use the
- * template to get the correct type of pointer from a derived class.
- */
- template
- Type *ref() {
- addRef();
- return static_cast(this);
- }
-
- /**
- * Releases a reference that was acquired earlier with ref(). The
- * object destroys itself when the reference counter hits zero.
- */
- void release();
+ void addRef(dint count = 1) {
+ _refCount += count;
+ DENG2_ASSERT(_refCount >= 0);
+ }
- protected:
- /**
- * Modifies the reference counter. If the reference count is reduced to
- * zero, the caller is responsible for making sure the object gets
- * deleted.
- *
- * @param count Added to the reference counter.
- */
- void addRef(dint count = 1) {
- _refCount += count;
- DENG2_ASSERT(_refCount >= 0);
- }
+ /**
+ * When a counted object is destroyed, its reference counter must be
+ * zero. Note that this is only called from release() when all
+ * references have been released.
+ */
+ virtual ~Counted();
- /**
- * When a counted object is destroyed, its reference counter must be
- * zero. Note that this is only called from release() when all
- * references have been released.
- */
- virtual ~Counted();
+private:
+ /// Number of other things that refer to this object, i.e. have
+ /// a pointer to it.
+ dint _refCount;
+};
- private:
- /// Number of other things that refer to this object, i.e. have
- /// a pointer to it.
- dint _refCount;
- };
-}
+} // namespace de
#endif /* LIBDENG2_COUNTED_H */
diff --git a/doomsday/libdeng2/include/de/data/record.h b/doomsday/libdeng2/include/de/data/record.h
index 494f9d6411..133ba31aa7 100644
--- a/doomsday/libdeng2/include/de/data/record.h
+++ b/doomsday/libdeng2/include/de/data/record.h
@@ -30,302 +30,303 @@
#include