On 2013-08-15 00:29, Marek Janukowicz wrote:
I need to have a generalized "settings" functionality that should work like
this:
* I need to be able to add this to a class
* each setting has its name, description, type and default value
* I need to iterate over all settings for given object

API would more or less look like:
class A {
  ... here I somehow define a setting called "maxTime"
}

A a = new A();

auto b = a.settings["maxTime"].value; // b would contain default value,
because it wasn't set explicitly yet
string s = a.settings["maxTime"].description; // s would contain setting
description
a.settings["maxTime"].value = 10.seconds; // This would only work if maxTime
setting is of type duration
foreach( name, value; a.settings ) ...

Now the problem that I have is with storing those settings. What I've come
up with so far are either Variants or templated structs (either really
templated and type parametrized structs returned from template functions).
The problem with variants is that I don't know how to force the value to be
of certain type (variant accepts anything). As for templates and structs I
tried something like:

auto setting (string name, string description, T, T deflt)() {
   struct Setting {
     string name = name;
     T value;
   }
   return Setting(name, deflt);
}

but then I don't know if there is any way to build an array of those to be
able to iterate over them.

I know generally there should be some kind of "setting definition" defined
on class level that would keep shared information (like names and defaults)
and then per-instance data containing just actual values, but I don't really
care and any solution where this shared information is copied for every
instance would also be fine.

I know the description above is a bit messy (it's quite late now), but
hopefully you can get the picture. Any ideas how to approach this problem?


Perhaps you can do something like this:

struct Setting (T, string desc)
{
    T value;
    enum description = desc;
    alias value this;

    this (T value)
    {
        this.value = value;
    }
}

class A
{
    Setting!(int, "foo bar") bar = 3;

    auto settings ()
    {
        return Tuple!(typeof(bar), "bar")(bar);
    }
}

void main ()
{
    auto a = new A;
    assert(a.bar.description == "foo bar");
    assert(a.bar.value == 3);
    assert(a.bar == 3);
    assert(a.settings.bar == 3);
}

In "settings" you should be able to:

1. Iterate over all fields of the type Setting using __tratis(derivedMembers)
2. Create and return tuple of all these fields

But then you won't be able to set the value via "settings".

Perhaps a variant is easier, but then you need to tell it what type to return, something like:

auto bar = a.settings["bar"].value!(int);

http://dlang.org/traits.html#derivedMembers

--
/Jacob Carlborg

Reply via email to