classCConfigurableObject
{CConfigurableObject(std::string name);
const std::string getName();
std::string cget(std::string name);
ConfigurationArray cget();
int getIntegerParameter(std::string name);
unsigned int getUnsignedParameter(std::string name);
bool getBoolParameter(std::string name);
double getFloatParameter(std::string name);
std::vector<int> getIntegerList(std::string name);
void addParameter(std::string name, typeChecker checker, void* arg, std::string defaultValue = std::string(""));
void clearConfiguration();
void configure(std::string name, std::string value);
void addIntegerParameter(std::string name, int defaultVal = 0);
void addIntegerParameter(std::string name, int low, int high, int defaultVal = 0);
void addBooleanParameter(std::string name, bool defaultVal = true);
void addEnumParameter(std::string name, const char** pValues, std::string defaultValue = std::string(""));
void addBoolListParameter(std::string name, unsigned size, bool defaultVal = true);
void addBoolListParameter(std::string name, unsigned minLength, unsigned maxLength, bool defaultVal = true, int defaultSize = -1);
void addIntListParameter(std::string name, unsigned size, int defaultVal = 0);
void addIntListParameter(std::string name, unsigned minlength, unsigned maxLength, int defaultVal = 0, int defaultSize = -1);
void addBooleanParameter(std::string name, bool defaultVal = true);
void addEnumParameter(std::string name, const char** pValues, std::string defaultValue = std::string(""));
void addBoolListParameter(std::string name, unsigned size, bool defaultVal = true);
void addBoolListParameter(std::string name, unsigned minLength, unsigned maxLength, bool defaultVal = true, int defaultSize = -1);
void addIntListParameter(std::string name, unsigned size, int defaultVal = 0);
void addIntListParameter(std::string name, unsigned minlength, unsigned maxLength, int defaultVal = 0, int defaultSize = -1);
void addStringListParameter(std::string name, unsigned size, std::string defaultVal = "");
void addStringListParameter(std::string name, unsigned minLength, unsigned maxLength, std::string defaultVal = "", int defaultLength = -1);
static bool isInteger(std::string name, std::string value, void* arg);
static bool isBool(std::string name, std::string value, void* arg);
static bool isEnum(std::string name, std::string value, void* arg);
static bool isList(std::string name, std::string value, void* arg);
static bool isBoolList(std::string name, std::string value, void* arg);
static bool isIntList(std::string name, std::string value, void* arg);
static bool isStringList(std::string name, std::string value, void* arg);
static isEnumParameter makeEnumSet(const char** values);
static bool strToBool(std::string value);
typedef std::pair<typeChecker, void*> TypeCheckInfo;
typedef std::vector<std::pair<std::string, std::string> > ConfigurationArray;
struct limit {bool s_checkMe;
long s_value;
limit();
limit(long value);
} ;typedef std::pair<limit, limit> Limits;
typedef std::set<std::string> isEnumParameter;
typedef struct _ListSizeConstraint {limit s_atLeast;
limit s_atMost;
} ListSizeConstraint typedef struct _isListParameter {ListSizeConstraint s_allowedSize;
TypeCheckInfo s_checker;
} isListParameter;typedef void (*ConstraintFreer)(void*);
typedef struct _DynamicConstraint {ConstraintFreer s_Releaser;
void* s_pObject;
} DynamicConstraint, *pDynamicConstraint; struct flimit {bool s_checkMe;
float s_value;
flimit();
flimit(float value);
};typedef std::pair<flimit, flimit> FloatingLimits;
typedef std::vector<isEnumParameter*> EnumCheckers;
};
This class is the ultimate base class of the CReadoutModule
object passed to device driver onAttach
methods.
It manages the configuration database of a configurable object.
The interaction of a configurable object or an object that embeds configuration via delegation is:
The object defines a configuration that consists of a set of named parameters and initial values. Each configuration value can have a constraint function attached to it that is called prior to allowing the value to assume a new value.
Through these constraint functions parameter values can' be very strongly typed (e.g. not just parameter must be an integer but parameter must be an integer in this range).
Pre packaged constraint functions and convenience functions make it easy to set up most types of constraints, however if something special is required client code can implement a special constraint.
At some point in the lifetime of a configurable object,
the object is configured. This is usually done by creating
(the CCUSB framework does this for you) a command or
command ensemble that accepts configuration name/value
pairs and passes them to the configure
method. This method will invoke the constraint checker
and, if successful, modify the value of the configuration
parameter. If the new value fails the constraint, a
std::string exception is thrown and should
be caught and reported at some level by the caller.
Again for CCUSB device drivers this is transparent.
Configurable objects can query their configuration. The constraint checkers ensure that each value has the type and range constraints required of that parameter. Semantics, however must be enforced and applied by the object that uses the configuration.
It is always possible to get a stringified value for each configuration item (in fact configuration items are stored as strings). Convenience methods allow for clients to fetch conversions of those strings to a rich set of types.
CCUSB device drivers normally fetch and process their
configurations when their
Initialize
and addReadoutList
methods
are invoked.
For the full set of methods see the METHODS section below. The pre-defined constraint checkers additionally make use of several data types which are described in PUBLIC VARIABLES, TYPES and CONSTANTS further below.
CConfigurableObject(std::string name);
Constructs a configurable object. CCUSB device
drivers have this construction performed for them.
Configurable objects have names to allow them to be
placed in some sort of configuration dictionary by the
application. the name
parameter supplies the configuration name.
If names are used, it's likely a good thing to ensure that unique names are chose for each configuration namespace the application maintains. This is not enforced by the constructor, however.
const std::string getName();
Returns the name of the configuration. This is the value of the parameter passed to the constructor.
std::string cget(std::string name);
Returns the string value of the configuration parameter
name
. If the parameter was
not defined a string exception is thrown.
In situations where you don't know the set of configuration
parameters that have been defined, see the overloaded
cget
method described next.
CConfigurableObject::ConfigurationArray cget();
Gets the entire configuration of the module as name value pairs. CConfigurableObject::ConfigurationArray is described fully in PUBLIC VARIABLES, TYPES and CONSTANTS below, however you can think iof it as a vector of std::string pairs of configuration parameter name and value.
int getIntegerParameter(std::string name);
Invokes cget
on the
name
configuration parameter.
The resulting string is converted to an integer and
returned, if possible. If the string is not a valid integer,
a string exception is thrown.
Note that this and other convenience methods for
getting parameter values converted to specific data
types pass any exceptions from cget
on up to the caller.
unsigned int getUnsignedParameter(std::string name);
Same as getIntegerParameter
,
however the conversion to an unsigned value is attempted.
This is recommended for e.g. base addresses.
bool getBoolParameter(std::string name);
Invokes cget
and attempts
to convert the resulting string to a bool
value which is returned if successful. A rather
rich set of values can be converted to bools.
Failure to convert to a bool throws a string exception.
double getFloatParameter(std::string name);
Uses cget
to retrieve the
value of the name
configuration
parameter. The string is converted to a
float and
returned. If the string is not a valid
float, a string exception is thrown.
std::vector<int> getIntegerList(std::string name);
Uses the cget
method to
obtain the configuration parameter name
.
The string is treated as a Tcl list which is composed
entirely of integers. If this assumption is correct,
a std::vector of the integers that made
up the list is returned. If the string is either
an invalid list or not entirely composed of elements
that can be converted to int,
a string exception is thrown.
void addParameter(std::string name, typeChecker checker, void* arg, std::string defaultValue = std::string(""));
This is the base mechanism for defining a configuration parameter. See the convenience methods below before using this as they may be easier to use.
name
is the name of the parameter
being added. By convention, this starts with the
- character (like options in Tk).
For example a module slot might be defined as a
-slot configuration parameter.
checker
is a pointer to the
constraint checking function. If no constraint checking
is required (e.g. the paramter is a pure string), pass
NULL for this parameter.
arg
is a parameter that is passed
without interpretation to the constraint checker.
See CONSTRAINT CHECKING below for more about how
constraint checkers are defined and called.
See also the descriptions of the built in constraint
checkers that are static members of this class, documented
later in this section.
defaultValue
is the initial
value supplied to the parameter. Note that this is
not constraint checked. This is
intentional as it allows you to require a parameter
setting by providing an invalid initial parameter
value.
void clearConfiguration();
Clear the configuration. This removes any parameter definitions as well as their value from the configuration database. In most cases this function is not necessary.
void configure(std::string name, std::string value);
Attempts to configure a parameter name
should be a configuration parameter name that has been
defined by addParameter
or its
convenience methods. value
is the new proposed value of the parameter.
The constraint checker, if any, is called for that parameter
and if it fails a string exception is thrown. Otherwise,
the new parameter value replaces the old one.
void addIntegerParameter(std::string name, int defaultVal = 0);
Convenience method to add an parameter
name
which is constrained
to be an integer parameter that has no range
requirements. The initial value of this parameter
will be defaultVal
void addIntegerParameter(std::string name, int low, int high, int defaultVal = 0);
Convenience methos that creates a parameter
(name
) that is constrained
to be an integer in the range
[low
..high
].
The initial value of the parameters is set to
defaultVal
which is not
checked against the limits.
void addBooleanParameter(std::string name, bool defaultVal = true);
Adds a parameter name
to the
configuration database which is contrained to be
a string that converts to a bool.
The initial value of the parameter will be
defaultVal
void addEnumParameter(std::string name, const char** pValues, std::string defaultValue = std::string(""));
Adds a parameter name
that is
constrained to be one of the values pointed to by the
pValues
array.
The initial value is defaultValue
The pValues
parameter should
be a pointer to a null terminated set of character pointers.
This sounds much harder than it is:
enumValues
can be passed in as the pValues
argument and will constrain the values of the configuration
parameter to be in the set
{red, greeen, blue}.
void addBoolListParameter(std::string name, unsigned size, bool defaultVal = true);
Adds a new configuration parameter
name
that is constrained to be
a valid Tcl list of bool strings of
exactly size
elements long.
The initial value will be set to size
elements of defaultVal
void addBoolListParameter(std::string name, unsigned minLength, unsigned maxLength, bool defaultVal = true, int defaultSize = -1);
Same as the previous method, however the
list size is constrained to be at least
minLength
and at most
maxLength
elements long.
The initial value is defaultSize
elements of defaultVal
If defaultSize
is outside
the length limits, it is forced to the closest limit.
void addIntListParameter(std::string name, unsigned size, int defaultVal = 0);
Adds a parameter that is constrained to be a fixed
length Tcl list of size
integer values.
The initial value of the list is size
copies of defaultValue
The range of values in the list is unconstrained. See the overloads below however.
void addIntListParameter(std::string name, unsigned minlength, unsigned maxLength, int defaultVal = 0, int defaultSize = -1);
Same as the previous method however the list can
have a size in the range
[minlength
..maxLength
].
the initial value of the list is defaultSize
elements of defaultVal
.
As for addBoolListParameter
,
if the defaultSize
parameter
is outside the range of valid list length it is forced
to the closest value. Thus the default value really
creates minlength
elements.
static bool isInteger(std::string name, std::string value, void* arg);
This is a static method that can be used as a constraint checker for integer parameters. When it is used, the constraint parameter shoule be NULL if no range checking is desired or a pointer to a Limits struct as described in PUBLIC VARIABLES, TYPES and CONSTANTS to describe which limits are desired and their values.
static bool isBool(std::string name, std::string value, void* arg);
This is a static method that can be used as a constraint checker for boolean parameters. When used, the constraint parameter should be NULL.
static bool isEnum(std::string name, std::string value, void* arg);
Constriaint checker fora n enumerated type. When used, the constraint parameter should be a pointer to an std::set<string> which has elements for each valid enumerator value.
static bool isList(std::string name, std::string value, void* arg);
General constraint checker for a parameter that must look like a Tcl list. The constraint parameter is a pointer to an isListParameter struct as defined in PUBLIC VARIABLES, TYPES and CONSTANTS This structure should be filled in to provide limits on the number of list elements the list can have. A constraint checker that is applied to each list element can also be supplied.
static bool isBoolList(std::string name, std::string value, void* arg);
Constraint checker for a Tcl formatted list of
booleans. The constraint parameter shouild be a
pointer to a ListSizeConstraint
described in PUBLIC VARIABLES, TYPES and CONSTANTS.
This should set limits on the size of the list.
isBoolList
will ensure
that the elements of the list are booleans.
static bool isIntList(std::string name, std::string value, void* arg);
Constraint checker for a list of integers. The constraint parameter should be a ListSizeConstraint that describes the allowed list sizes. The checker will ensure that the elements fo the list are all valid integers. At present, this checker does not support checking the values of the list elemeents against range limits.
You could manually construct the isListParameter
structure to do this and use isList
if required.
static bool isStringList(std::string name, std::string value, void* arg);
Constraint checker for lists of strings. The constraint parametr is a ListSizeConstraint that defines the allowed sizes of the list.
static isEnumParameter makeEnumSet(const char** values);
Helper function that converts a null terminated array of pointers to strings into a isEnumParameter constraint parameter.
static bool strToBool(std::string value);
Convenience function that converts a string to a boolean or throws an exception if the resulting string cannot be converted.
The class definition in the SYNOPSIS section above shows a large number of type definitions for this class. Almost all of these types are structures used by the built in constraint checkers.In most cases, if you use the convenience functions to define your parameters you won't need to know the details of these types.
The remainder of this section describes these types and the constraint checkers they belong to.
typedef std::vector<std::pair<std::string, std::string> > ConfigurationArray;
The ConfigurationArray is returned from
one of the overloads of the cget
method. This type is a vector of pair. The first element of each pair
is the name of a parameter while the second element is it's current
value.
The following fragment of code shows how to use this
to dump the current configuration of a configurable
object pointed to by pConfig
bool s_checkMe;
long s_value;
limit();
limit(long value);
} ;, typedef std::pair<limit, limit> Limits;
These data types are used with the
isInteger
constraint
checker. Each limit data type
represents a range limit that may or may not be
checked according to the state of its
s_checkMe
flag.
Limits is a pair of limit structs where the first one represents the lower limit and the second one the upper limit.
typedef std::set<std::string> isEnumParameter;
The isEnumParameter is used by the
isEnum
method
to validate parameters that are enumerate parameter.
The actual type is a set of the character strings
that are allowed to be assigned to the parameter value.
typedef std::pair<typeChecker, void*> TypeCheckInfo;
, typedef struct _ListSizeConstraint {
limit s_atLeast;
limit s_atMost;
} ListSizeConstraint, typedef struct _isListParameter {
ListSizeConstraint s_allowedSize;
TypeCheckInfo s_checker;
} isListParameter;This set of types are used to validate lists. The isListParameter is what is used to validate lists. This consists of two chunks;
s_allowedSize
is used
to validate the size of a list. It is a
ListSizeConstraint which allows you to
specify minimum and maximum list sizes. The list
size limits are inclusive so you can specify a
fixed size list by setting both
s_atLeast
and s_atMost
to be the same.
s_checker
is a constraint
checker and its parameter used to validate each
item in the list. This is applied after the
string is determined to be a valid list and
after the size of the list has been checked against
the limits defined by s_allowedSize
s_checker
TypeCheckInfo which is a pair whose
first element is a pointer to the actual constraint
checking function and whose second is a pointer to data
passed to the constraint checker without
interpretation. For more information about how
constratin checkers work see
CONSTRAINT CHECKING below.
bool s_checkMe;
float s_value;
flimit();
flimit(float value);
};, typedef std::pair<flimit, flimit> FloatingLimits;
These types specify floating point limits in a mannger analgous to integer limits.
Constraint checking is the CConfigurableObject
class's way to enforce type safety and other constraints on
the values of configuration parameters.
When a parameter is created with addParameter
,
The caller has an option to provide a constraint checker and
a parameter that provides extra information to the constraint
checker that can parameterize the constraints it checks.
A constraint checker is just a function of the form:
When the configure
method is called
for a parameter name that has a constraint checker
attached to it, that checker is called and passed the parameters
shown in the code fragment above:
name
Is the name of the parameter being configured.
newValue
Is the proposed new value for the parameter.
pClientData
Is the constraint parameter passed to
addParameter
passed without interpretation or modification.
The constraint checker is expected to return
true if the proposed newValue
is acceptable by the constraint checker and false
if not. If true is returned the parameter
value is modified to newValue
otherwise
a string exception is thrown and the parameter value is not
modified.
The CCUSB framework catches string exceptions thrown by
CConfigurableObject
and converts those
into configuration file processing error messages. Any configuration
file processing error is reported and aborts the start of the
run that caused it.