Best practice for managing application parameters?

S

stephen.diverdi

I have a question about what's the best way to handle something in C++
without a lot of redundant code and void*s because I don't seem to be
able to avoid them both. I've run into it before and always sort of
hacked something together, but I'd really prefer a more elegant
solution.

I have a parameter struct that I store some values of varying type in:

struct params_t
{
int count;
bool render;
float alpha;
};
params_t params;

This struct gets used many different places. For example, it can be
filled with values from a dialog box like:

params->count = Dialog->GetIntegerValue( kParamsCountItem );
params->render = Dialog->GetBooleanValue( kParamsRenderItem );

where kParamsCountItem and kParamsRenderItem are static constants.
Creating the dialog box uses similar functions to set default values:

Dialog->SetIntegerValue( kParamsCountItem, 1 );
Dialog->SetBooleanValue( kParamsRenderItem, false );

There's other code the struct has to interact with that operates more
like this:

dictionary->GetIntegerValue( "count", &params->count );
dictionary->GetFloatValue( "alpha", &params->alpha );

Currently, every time I add a new paramter, or I change a default
value or something, I have to edit a bunch of different things - I
need to update the places where default values are set, I need to add
functions to the dialog handling code, I need to add lines to the
dictionary handling code, etc. This is spread over a couple files and
is tedious and error-prone. I'd like to have something where I define
the set of available parameters in one place statically, and then each
of these separate functions (i.e. dialog, dictionary, etc.) just
iterates over a the set of available parameters. The trouble is my
parameters are different types. Here's the kind of thing I'm looking
at now (which I recognize is a mess):

enum { TYPE_NONE = 0, TYPE_INT, TYPE_BOOL, TYPE_FLOAT };
struct param_spec_t
{
int type;
size_t offset;
const char *str;
float defaultval;
int dialog_id;
};

static const param_spec_t param_spec[] = {
{ TYPE_INT, offsetof( params_t, count ), "count", 1.0f,
kParamsCountItem },
{ TYPE_BOOL, offsetof( params_t, render ), "render", 0.0f,
kParamsRenderItem },
{ TYPE_FLOAT, offsetof( params_t, alpha ), "alpha", 0.5f,
kParamsAlphaItem },
{ 0, 0, NULL, 0, 0 } };

This makes the code to interact with e.g. the dialog box unpleasant:

params_t *params;
for( int i = 0 ; param_spec[ i ].type ; ++i )
{
void *ptr = ( ( void * )params ) + param_spec[ i ].offset;
switch( param_spec[ i ].type )
{
case TYPE_INT:
*( int * )ptr = Dialog-
GetIntegerValue( param_spec[ i ].dialog_id );
break;
case TYPE_BOOL:
*( bool * )ptr = Dialog-
GetBooleanValue( param_spec[ i ].dialog_id );
break;
case TYPE_FLOAT:
*( float * )ptr = Dialog-
GetFloatValue( param_spec[ i ].dialog_id );
break;
}
}

Anytime I want to iterate through the parameters, this kind of mess is
necessary. So, what's a better way to accomplish this? I'd rather
not throw out type data and have to use these switch statements on an
enum, but how can I store a set of parameters of different types? And
how can I avoid the offsetof mess? Any suggestions are very welcome!
Thanks,

-stephen diverdi
(e-mail address removed)
 
M

Martin Eisenberg

Hendrik said:
(e-mail address removed) wrote:
I'd like to have something where I define the set of available
parameters in one place statically, and then each of these
separate functions (i.e. dialog, dictionary, etc.) just
iterates over a the set of available parameters. The trouble
is my parameters are different types. [...]

Have a look at compile-time lists. Tuples (come with boost
and TR1) might be what you're looking for.

Boost::Fusion can iterate over heterogeneous sequences.
http://www.boost.org/doc/libs/1_37_0/libs/fusion/doc/html/fusion/introduction.html


Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top