Re: Properties on interfaces



On 13 Feb 2003, Owen Taylor wrote:

> Fooling around with this a little more, two fairly obvious
> issues came up:
>
>  * What get_property/set_property methods get called?
>    Maybe the ones for the type for which add_interface() is called?
>    But that doesn't allow overriding the implementation in
>    derived classes, and also doesn't

i don't see good alternatives for the property setter and getter,
other than the normal property setters and getters in the instance
type implementaiton.

>  * What to do about property IDs, since they are different
>    for each class that has a given interface?

that's yet another problem there, it doesn't come up if we
use the established property functions though.

> What I was thinking about to solve these problems is something
> like:
>
>  g_object_class_install_interface_property (file_chooser_dialog_class,
>                                             PROP_FILENAME,
>                                             "filename",
>                                             GTK_TYPE_FILE_CHOOSER);
>
> Which says to forward PROP_FILENAME/filename to the "filename" property
> of the GtkFileChooser interface.
>
> This would be implemented by inserting a (hidden) "proxy" param-spec
> into the paramspec pool.

i think this is quite pointless. the type implementing an interface has
to forward a proxy property to the interface class, which in turn just
demands that the type implements accessors for this property while
implementing the interface? (sounds ridiculous, doesn't it? ;)

as i wrote above, i don't at all buy into implementing property setting/
getting in other methods than the established accessors (we already
force C OO users into writing lots of overhead functions).
what keeps us from doing that? quoting your original email:

> For the methods and signals, this works well, but GtkFileChooser will
> presumably have a bunch of properties. We could just use a convention
> that objects implementing GtkFileChooser need to implement a set of
> properties but this is ugly, will cause duplication of doc strings,
> and won't work well in the documentation.

so you raise:
1) uglyness
2) duplication of doc strings
3) problems retrieving property documentation
i would like to add:
4) error checking (enforcing) validity of interface property
   implementations. i.e. automated checks that the conventions
   are obeyed.
5) natural way to override property behaviour in derived classes
6) handling CONSTRUCT properties

thoughts on the issues raised:
1 - i can't really help you with feeling ugly (about implementing
    the properties in the instance class i mean ;)
    however, in case that helps to lessen your feelings, i don't
    think it's ugly if the interface just demands property implementations
    and the classes simply obey that by providing implementations.
2 - a possible solution to avoid duplication of doc strings could be
    pspecs "forwarding" blurbs and nicks. that'd work like:
    g_object_class_install_property (gobject_class, /* GtkLabelClass */
                                     PROP_LABEL,
                                     g_param_spec_string ("label", NULL /*nick*/,
                                                          NULL /*blurb*/,
                                                          NULL /*default*/,
                                                          G_PARAM_READWRITE | G_PARAM_TRANSLUCENT));
    and in the interface:
    g_interface_class_install_property (iface_class,
                                        g_param_spec_string ("label", _("Label"),
                                                             _("The text of the label"),
                                                             NULL /*default*/,
                                                             G_PARAM_READWRITE));
    or alternatively in a parent class (#51748):
    g_object_class_install_property (iface_class, /* peek_parent (GtkLabelClass) */
                                     g_param_spec_string ("label", _("Label"),
                                                          _("The text of the label"),
                                                          NULL /*default*/,
                                                          G_PARAM_READWRITE));
    so when a property "label" is looked up on the object, a
    translucent (or shallow) pspec is found that doesn't have a nick/blurb
    itself. this causes the lookup to proceed as usual, until the parent
    class' or the respective interface class' "label" pspecs are found.
    these are used by the translucent pspec to hand out nick/blurb strings
    upon invocation of g_param_spec_get_{nick|blurb}() despite not being
    able to provide them itself. the process of doing so might sound
    complicated, but is fully transparent to the user except for
    specifying G_PARAM_TRANSLUCENT.
3 - retrieving property documentation doesn't need to change a whole lot.
    g_object_class_list_properties() will list additional properties that
    are also interface properties. if that is not desired, we can add a
    new function (say g_object_class_list_non_interface_properties()) which
    strips properties covered by interfaces from the list returned by
    g_object_class_list_properties().
    and alongside g_interface_class_install_property(), we'll
    have g_interface_class_list_properties() to list the proeprties
    of an interface.
4 - g_interface_class_install_property() will have to hand over pspecs
    to the GObjectClass implementation in some kind of way. i'm thinking
    about:
    /* --- interface implementation API --- */
    void  g_interface_class_install_property  (GTypeInterface *iface,
                                               GParamSpec     *pspec);
    /* --- specific to fundamental type implementations --- */
    void  g_interface_class_register_property_handler (GType instance_type,
                                                       void (*handler) (GTypeInterface*,
                                                                        GParamSpec*));
    handler() is to be supplied by GObjectClass and can throw warnings
    if iface pspecs have different types than instance pspecs, or if
    similar programming errors are spotted. (handler() is called to install
    the interface pspecs on an object class *after* object_class_init()
    has completed)
5 - by keeping the property implementations as established (with the
    extension of G_PARAM_TRANSLUCENT and automated checks against properties
    installed on the interface through g_interface_class_install_property()),
    we also keep the ability to override property implementations in derived
    classes as usual.
6 - i'm not sure allowing interface properties to be CONSTRUCT or
    CONSTRUCT_ONLY properties is a good idea. though i can't pinpoint a good
    reason for why, i'd rather not allow this initially. anyone has
    a good usage case for actually having construct properties on interfaces?

> This is perhaps somewhat related to:
>
>  http://bugzilla.gnome.org/show_bug.cgi?id=51748
>
> Where the problem is that to change the default value or implementation
> of a property, you have to install an entirely new paramspec,
> duplicating the doc strings.
>
> Regards,
>                                         Owen
>

---
ciaoTJ





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