RE: Glib - Object Properties



> -----Original Message-----
> From: Tristan Van Berkom [mailto:tvb gnome org] 
> Sent: Tuesday, June 14, 2005 8:11 AM
> To: Shay Harding
> Cc: gtk-list gnome org
> Subject: Re: Glib - Object Properties
> 
> Shay Harding wrote:
> >  
> > Currently, I can get/set properties no problem. The issues 
> I am having 
> > pertain to how to trap errors during object construction for 
> > CONSTRUCT_ONLY properties. If I have a property with flags set to:
> >  
> > G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE
> >  
> > then I supposedly can only set the property while calling 
> > g_object_new(). This is only kind of true. If I attempt to set the 
> > property after g_object_new() is called, Glib simply emits 
> a warning, 
> > but still allows the property to be set. Actually, this is 
> only true 
> > if I call g_object_set_property() within my 
> xxx_set_property() function.
> > The problem is g_object_set_property() returns void so I 
> have no way 
> > to catch errors (i.e. property set outside of a constructor).
> >  
> > How can CONSTRUCT_ONLY actually be enforced and not emit 
> warnings to 
> > stdout/stderr? From what I can tell, I can't even write my 
> own code to 
> > do this since I have no access to the static global 
> 'pspec_pool' and 
> > the GParamSpec passed to my xxx_set_property() function after 
> > construct is NULL (incidentally it seems to always be NULL 
> after the 
> > object is constructed even without CONSTRUCT_ONLY set in flags).
> >  
> > Thanks for any insight as to why this all works like this and any 
> > advice on enforcing policies.
> 
> Hi,
>     "Construct only" properties were only enforced in GTK+ >= 
> 2.4, If you are using the latest GTK+, then your 
> xxx_set_property method "shouldn't get envoked" when setting 
> properties on your object.
> 
> You should never call g_object_set_property () from inside 
> your xxx_set_property method, this will result in endless 
> recursion, the set_property method is a private method used 
> only to actualy persist the transported GValue on your actual 
> instance.
> 
> Cheers,
>                             -Tristan
> 

Thanks for the reply. I am using glib 2.6.4 and did finally figure out
what I was doing wrong for the CONSTRUCT_ONLY properties. It was
basically me not understanding what was going on. After looking at the
source code some more in gobject.c, I realized I didn't need to call my
own xxx_set_property() function, but simply call
g_object_set/get_property(), which then called my xxx_set_property()
method and checked on CONSTRUCT_ONLY flags and such.

I think I have all that sorted out now. I am still having serious
troubles trying to get my test objects to work (just to figure out how
the glib code works). I basically created an "Option" object (to store
command line options as objects; is an easy way to get familiar with the
glib code). I figured I could have a base abstract class "Option" and
then implement things like IntOption, BoolOption, StringOption. The only
difference between all of them is the type of data to store.

I created the Option class as (standard typedefs and macros left out):

struct _Option {
    GObject parent_instance;
    OptionPrivate *priv;
};

struct _OptionClass {
    GObjectClass parent_class;
};

struct _OptionPrivate {
    gchar *name;
    gpointer value;
};

// The GET_PRIVATE macro for this simply tells it
// to return the OptionPrivate struct type. 
struct _IntOption {
    Option parent_instance;
    OptionPrivate *priv;
};

struct _IntOptionClass {
    OptionClass *parent_class;
};


I have the option_class_init() which installs the properties and adds
the private struct. It all works for the base Option type (until I set
it to abstract anyway). When I try to create an "IntOption" type and
tell it to use "Option" as a parent, it kind of falls apart (can't find
any good examples of this; the testobject.c code is not much help). I
have it working, but it's pretty hacked IMO.

I have an option_init both types use as their class_init function (I
figure out which type called it via IS_XXX_CLASS macro. I couldn't
figure out how to get the properties installed if IntOption had its own
class_init function. They don't seem to chain up automatically and I
didn't see a way to do it manually (constructor perhaps?).

I created option_set/get_property() functions that set the value
gpointer with g_value_get_pointer(). This is fine for setting, but I
wanted to return the actual data type on the get() call (i.e. int,
boolean, gchar*). I can do it by writing an init function and get
function for each type, but that seems pretty redundant. I have
currently accomplished it with macros (i.e. INT_OPTION_GET_VALUE(obj))
which just calls g_object_get_property() and casts the returned gpointer
appropriately. This seems kind of messy and a hack.

I was wondering if there is a "proper" way to do it within the glib
object framework without duplicating a lot of code?


Thanks for any insight you can provide.


Shay



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