Best practice for managing application parameters?

Discussion in 'C++' started by stephen.diverdi@gmail.com, Nov 10, 2008.

  1. Guest

    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
    , Nov 10, 2008
    #1
    1. Advertising

  2. Hendrik Schober wrote:
    > 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

    --
    Quidquid latine scriptum est, altum videtur.
    Martin Eisenberg, Nov 11, 2008
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul
    Replies:
    3
    Views:
    401
  2. tshad

    Passing parameters best practice

    tshad, Aug 9, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    3,832
    sloan
    Aug 9, 2006
  3. * Tong *
    Replies:
    2
    Views:
    2,606
    Joe Smith
    Sep 28, 2006
  4. Steve
    Replies:
    3
    Views:
    2,520
    Berlin Brown
    Jan 6, 2007
  5. oldyork90
    Replies:
    1
    Views:
    148
    Jeremy J Starcher
    Sep 10, 2008
Loading...

Share This Page