Re: syntactic sugar vs. design



Byron Ellacott wrote:
> 
> and preserve the simple data model while providing convenient high level
> APIs when they are needed.  As an aside, I feel the list type should be
> dropped entirely in favour of this approach, as the contents of the list
> here can easily be either simple or complex types, and presenting one
> solution to both problems seems neater; the list type is also the most
> complicated part of the data model as thing stand.  Less easily, they
> could also be mixed types, with a stronger focus on GConfSchema use, but
> this isn't a matter under discussion.

I must admit that coming from an engineering background I can't help but
think of vectors and ordered-pairs as fundamental types :).  Hence I
don't have a problem with them.  Granted they can be abused by lazy
developers, but then again Strings are already being abused worse than
anything I can think of with lists.  Of course I can't see how we can
avoid such kludging unless we provide more expressive GConfSchema
support and a more convenient API.  I have already given my thoughts on
how such an API could look, and the idea of using a DOMlite API also
appeals to me.  I would however suggest that while we can draw from the
prior art in the XML committees, we avoid the temptation to just try and
mascarade GConf as XML.  GConf and XML solve different problems, and
have very different heritages.

In that vein I would like to suggest that we discuss what such an API
might look like, and if it is necessary/desired to provide syntactic
sugar for struct storage/retrieval.

My initial proposal would be along the lines of :

/apps/myapp/colour/r = 0xff
/apps/myapp/colour/g = 0xee
/apps/myapp/colour/b = 0xdd

===
typedef struct Colour_ {
  int r, g, b;
} Colour;

int main() {
...
    GNode *tree = gconf_get_tree("/apps/myapp/colour");
    Colour colour;
    colour.r = gconf_tree_get_int(tree->children);
    colour.g = gconf_tree_get_int(tree->children->next);
    colour.b = gconf_tree_get_int(tree->children->next->next);

/* or with syntactic sugar */
...
    GConfStruct *mystruct = gconf_new_struct("r",
G_STRUCT_OFFSET(Colour, r), 
                                             "g",
G_STRUCT_OFFSET(Colour, g), 
                                             "b",
G_STRUCT_OFFSET(Colour, b));
...
    Colour *colourptr = gconf_get_struct(mystruct,
"/apps/myapp/colour");
}

Now I envisage the data in GConf being available in 4 forms:

GConf Engine - accessed via current gconf API.

GNode based tree - accessed via helper functions, note that if we keep
the node's data opaque we leave ourselves the option of doing
late-binding/caching/direct schema lookups, etc.

Struct based synsugar - allow the developer to create read/write
templates using G_STRUCT_OFFSET to permit easy storage/retrieval of
structs.

SML file - integrates with GMarkup to permit the serialisation of a
GConf tree to a file.

The first three and last three forms should be trivially interchangable,
so there should be:

== Engine <-> Value ==
GConfValue *gconf_engine_get(GConfEngine *, gchar *, GError **);
gboolean gconf_engine_set(GConfEngine *, gchar *, GConfValue *, GError
**);

== Engine <-> Tree ==
GNode *gconf_engine_get_tree(GConfEngine *, gchar *, GError **);
gboolean gconf_engine_set_tree(GConfEngine *, gchar *, GNode *, GError
**);

== Engine <-> Struct ==
gpointer gconf_engine_get_struct(GConfEngine *, gchar *, GConfStruct *,
GError **);
gboolean gconf_engine_set_struct(GConfEngine *, gchar *, GConfStruct *,
gpointer, GError **);

== Tree <-> Struct ==
gpointer gconf_tree_to_struct(GConfStruct *, GNode *);
GNode *gconf_struct_to_tree(GConfStruct *, gpointer);

== Tree <-> SML ==
gboolean gconf_tree_to_sml(int fd, GNode *);
GNode *gconf_sml_to_tree(int fd);

== Struct <-> SML ==
gboolean gconf_struct_to_sml(int fd, GConfStruct *, gpointer);
gpointer gconf_sml_to_struct(int fd, GConfStruct *);


Now I haven't given much thought to this API, so I doubt this is
suitable as it stands, but it seems to me to be a reasonable starting
point for a discussion of what it should eventually look like.

Andrae




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]