Simulation users often want to run many instances with slightly different parameters. ns-2 had a system whereby users could change the value of a C++ variable if it was suitably bound (see the tcl/lib/ns-default.tcl script of ns-2).
In ns-3, we have developed the following system for default values, and have hooked it into a command-line argument parsing facility. The basic idea is to use a templated global variable facility to store bindings between string names of variables, ``help'' text on allowable parameters, and the default value itself. This avoids users needing to rebuild core libraries to change parameters, and allows users to avoid rebuilding any files at all if the command-line facility is used.
The program in samples/main-default-value.cc shows how this facility can be used. Briefly, any variable of a supported type in the system can be bound to a unique string by first declaring a static variable such as
static IntegerDefaultValue<int> defaultTestInt1 ("testInt1", "helpInt1", 33);which declares that testInt1 is an integer with a default value of 33. The second parameter is a string that can be modified by the developer to encode whatever information is useful (e.g., units). Then, any actual integer in the system can be later assigned to the value of defaultTestInt1, as typically done in an object's constructor.
If a variable in the system has been bound to the string ``testInt1'', the following C++ statement (typically invoked near the top of a main program) will cause it to be initialized instead to e.g. the integer value 57:
Bind("testInt1", "57");
While a user can change this default by modifying the main program, the command line can be used as well. Running "./sample-default-value -help" will cause a list of possible configurable values to be printed out. For this example, the following string is printed:
--testInt1=[int32_t(-2147483648:2147483647):33] helpInt1This tells the user that testInt1 is of type int32_t with a range of values specified between the parentheses, and a default value of 33 (that can be overridden).
This facility can also be used to swap out the type of an object at run-time, if the particular class has been integrated into the system. For instance, the file examples/simple-point-to-point.cc shows a line as follows:
Bind ("Queue", "DropTailQueue");where DropTailQueue is a subclass of class Queue. This type of binding will allow callers of the Queue::CreateDefault () factory method to obtain a suitably subclassed Queue object.
Consult the samples/main-default-value.cc example program for more information on how to use this facility.