Re: New 'GObject' as base for GtkObject?



On Fri, 10 Dec 1999, Karl Nelson wrote:

> > On Thu, 9 Dec 1999, Karl Nelson wrote:

> The short point he was trying to make is that
> an object system is good, but it does not completely get you to the
> same point that a language enforcing those constraints would give.
> Thus people either from inexperience or "clever" use of they system
> will create new and unbindable patterns.  This inconsistancy 
> can completely defeat even the most elegant plans for wrapping.

ok, i now understand that with "consistency" you mean consistent use
of the object system for varous kinds of structures.
there are certainly places in gtk/gdk where it we should use some
GObject-alike base type and greatly aid language bindings with that,
that's especially the case with some Gdk structures.
but as owen already pointed out, the GtkObject system doesn't allow
for such fine grained object hirarchies as you would use them on C++
it doesn't make a whole lot of sense to make GList derive from some
object base structure for instance.
Gtk+ is not only a toolkit created for language bindings, but also
to be usable in C, so you will come around structures that are there
for convenient use in C programs and not to create bindings from,
rather the bindings need to implement their own language-specific
interfaces sometimes and wrap that onto the C interface.
i don't know how you handle GtkItemFactoryEntry in C++, but i
defintely don't see a point in having that be implemented as an object,
the whole point about this structure is to be able to layout C arrays
in a compact way and create whole menu hirarchies from that.
you could adapt that for C++ with a wrapper structure Gtk_ItemFactoryEntry
if you wanted to and/or cookup your own interface e.g. like
factory.create_item ("path", "accelerator", function, "type");
C++ is actually the one language that should have the least headaches
with the provided C interfaces.

> > so if you'd shortly outline what consistancy you are talking about
> > and provide a pointer to that gtkprocess header generator you are
> > talking about, i'd apprechiate that.
> 
> Sure not a problem.  Consistancy would be to have the elements that
> are related always be related in the same way.  For example if I
> have a public signal exposed to the user it should have
>  
>   - the same name for its emit function and signal name should
>     always have the same relationship.  (Not like gtk+ functions
>     that have boo-bar and gtk_foo_boo_bar)

wait, one convention in gtk is actually to name emit functions (the
functions that emits the signal) after their signal name (or vice versa),
so if you have a ::boo_bar signal for a GtkFoo object, the function
should be named gtk_foo_boo_bar () and the class method (the vfunc called
upon the signal emission) should also be named boo_bar().
so what are you referring to here?


>   - the same meaning for the emit function and signal name.
>     (Some emit functions in gtk+ do different things when called
>     through a function and called directly.)

(i assume with emit function you mean the class vfunc here), class
methods that are called from signal emissions are part of the signals
implementation and shall never be called directly but only during
their signal's emission.

>   - the same arguments shared between signal and emit functions,
>     and the virtual function.

can you give a concrete example here? the signal emitting function
and the vfunc should normally have the same arguments (and the
signal must have the same arguments as the vfunc, otherwise
marshalling simply doesn't work).

>   - signals are either private or public.  (We are often told
>     by one gtk+ member that some signal is private don't bother
>     wrapping it, then we go to the tutorial and find an example
>     that hinges on that function being public.  Nothing should
>     be truely private unless no derived class can see or use it,
>     thus those private things really should just be thought of
>     as protected and we must wrap them.)

signals that are "private" usually shouldn't be signals, why
should they if you're not supposed to connect a handler to it.
i'm actually a bit confused about your terminology here, we don't
really introduce "public" and "private" signals, we just make
a distinction between signals that have to be emitted from
an object's implementation (usually because there's important
pre-/post-processing necessary) and signals that may be emitted
randomly by the object user on his own behalf.

> These are all done via convention in gtk+, but they are broken
> many times.  Every time they were broken we had to add another
> field parameter to our system.  At last count we had to recognize
> 9 different parameters which combined to form over 20 possible
> varients (many are mutially exclusive)

if you encounter places where gtk conventions/constraints are being
broken, special caseing them in your language binding is the worst
thing you can do. the correct way to handle such a situation is to
report the brokeness and fix things up in gtk. we don't come up
with random conventions late friday nights to get fun out of
breaking them.

> > personally i consider the quarked data a standard feature we should provide
> > there, especially to avoid hackery in class tress that derive from a GObject
> > without quarked data and figure the need for quarked data later on. those
> > class trees would probably end up using g_dataset_* functionality and would
> > then need support for dataset destruction in the base class (to invalidate
> > the object's dataset entry once the pointer is freed).
> > apart from that, support for datalists is simply required if we want the
> > signal system seperated as well, there'd be no facility to store the
> > object's handler list otherwise.
> > on the reference counting, that is also a definite requirement for GObject,
> > we can't get signal connections going without that and can't get proper
> > destruction (with weak reference callbacks as gtkobject has them) going
> > without that either.
> 
> I was thinking more allong the line of a multiple inheritance system
> where the base size was 4 bytes.  (pointer to the class)  This is
> below an object.  Sets of bases can be combined through SI or virtual MI.
> Although it is easier to define things that are always MI.  (thus
> preventing the problems that C++ gets into of having multiple copies
> within the classes.  Okay this is hard to imagine... I will
> compose a small sample system this weekend with those properties to
> give you an idea what I mean. 

multiple inheritance will definitely not be going into the libgobject
logic, for one this is an extremely tedious thing to imlement in C
efficiently and complexifies structure accesses by a significant
amount, and for another the existing GtkObject system would be really
hard to get going on top of that, if at all.
and finally i guess there'd be some non-C++ language binders who
are going to rip our asses off for that ;)


> OFF TOPIC
> 
> I have been wondering something about the gtk+ tool set.  I notice
> that the concept of a virtual function and a signal are very closely
> tied, but at the same time they appear seperately in a wealth of 
> combinations.  Part of this is because the signal has a pointer to
> the function that is virtual, but then it has flags for before, after
> and other fun things.  
> 
> In effect this is the opposite of Qt.  In Qt the vfunc is provided
> by the language and then calls the signal from the vfunc.  This allows
> you the freedom to chose to call the signal or not, and to chose
> the order of calling without all those flags.
> 
> Ie.  (C++ish psuedo code)

[...]

> Would it not have been simpler to have defined a signal and vfunc
> seperately  and in a more flexible relationship?  Was this
> intention to do the opposite of Qt or was this never thought about?

i don't actually think that peter's design goal for the signal system
was to be different from Qt back then ;) (the signal system was actually
designed pretty much exactly 3 years ago).

> I am not proposing that this be done, it would be a huge
> headache to change and not worth much at this point.  Still
> I found the differences between the two striking. 

i don't think you actually learned to like the power and flexibility
gtk's signal system provides, and are probably in doubt about it's
real purposes.

1) since in gtk you usually do *not* derive from a widget to slightly
   customize its behaviour (simply because the overhead for that is
   significantly higher in plain C as in real OO languages), a mechanism
   was required to still be able to configure a widget's behaviour in
   extensive ways.
2) also, as in any event-driven model with callback triggering, a flexible
   system was required to invoke different kinds of callbacks for different
   kinds of events with feedback on whether an event was handled or not (event
   propagation is undoable without that).
3) finally, with widgets representing certain GUI components that may or may
   not perform various actions and change state on their own behalf (well, on
   behalf of the GUI user actually, but they kinda have their own will as
   far as applications are concerned), a notification mechanism was
   required to keep the application code updated on what's going on with the
   widgets.

now the short answer this, the Gtk+ signal system was designed to cover
all three needs.

with signals being emitted for widgets that deliver events, and widgets being
able to implement their own event handlers through vfuncs you can have any
widget handle any event, override parent class' behaviour on event handling
where desired and thus actually get the whole widget concept working in the
first place (2).
then with user defined callbacks (signal handlers) that can be setup to get
called *prior* to the widget's event handlers and optionally intercept them,
you get the amount of flexible customization required as outlined in 1.
creating a signal for a widget while leaving the vfunc NULL (or leave it out
completely) and emitting it when certain state changes happened, finally gets
you the functionality required in 3.
since the latter type of signals serve mere notification nature and may get
emitted from various places, they do not necessarily have an emit function
exported through the widget's API and/or don't come with an actuall handler
implementation (this may be one of the cases you were referring to above,
i don't know).

of course gtk itself aa well as application code don't make that hard
of a distinction, you can connect to a signal that comes with an actuall
member implementation, eventhough you just want to get notified, and
sometimes we may even need to implement a member function for a signal
that was initially designed to serve pure notification.
this may sound silly to someone to someone who's already familliar with
gtk, but what i mean to point out here is:
having one system implementing all three mechanisms provides you with
great flexibility, but also blurs the distinction between the different
conepts (which is not necessarily a bad thing).

> 
> --Karl
> 

---
ciaoTJ



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