Re: New 'GObject' as base for GtkObject?
- From: Karl Nelson <kenelson ece ucdavis edu>
- To: gtk-devel-list redhat com
- cc: kenelson sequoia ece ucdavis edu
- Subject: Re: New 'GObject' as base for GtkObject?
- Date: Fri, 10 Dec 1999 10:22:23 -0800
>
> Karl Nelson <kenelson@ece.ucdavis.edu> writes:
>
> > > > - abstract callbacks in some way. A callback is not necessarily a
> > > > function pointer.
> > > >
> > >
> > > This is a good idea, complicated because you also have to abstract
> > > marshallers. Has any discussion gone in to how to do this?
> > >
> > > What about a signal-signature->marshaller lookup table used to find
> > > alternate marshallers. Then an additional flag passed to
> > > gtk_signal_connect_still_more_full() that specifies which marshaller
> > > set to use. So default handlers and connections done with
> > > gtk_signal_connect() use the default marshaller still. C++ bindings
> > > could pass an instance/memberfunction pair instead of a GtkSignalFunc
> > > to connect_still_more_full(), and then provide marshallers that
> > > invoked the instance/memberfunction pair.
> >
> > I have discussed a number of ideas with developers on the gtk+ irc.
> > Things like separating the marshaller from the argument launcher
> > have also been discussed. In Libsigc++, the marshaller is a
> > function that takes the new return value and old one
> > and combines them together, returning a code on whether to
> > continue the emission or not. This would avoid a lot of calls
> > to the emission stop. (The launcher is the slot
> > that processes the arguments from a list to a function call again.)
> > If you eleminate the global lists from the emission process the
> > system would be thread safe without needs for a global lock
> > like gtk+. However, the conclusion always seems to be "it would
> > have been nice, but it is too late now."
>
> Eh? I didn't get that opinion. I was certainly very positive
> on the idea of adding the abilility to have "TRUE return stops emission",
> and I think Tim was at least moderately in favor of that.
Sorry, I don't mean to imply that you were not positive to
the idea. But even my own conclusion to those ideas is "
a little to late for current code base". If there is a
2.0 version of the signal system I think the idea should be
there for consideration. (I agreed with you that it was too late
for now.)
>
> This does not mean that we would get rid of global emission
> lists, but if we moved GtkObject it to a libgobject, I'd definitely
> imagine adding the necessary locks to make it GLib-style thread
> safe. (That is, the internal data structures would be thread safe) -
> and make the emission lists per-thread.
(Owen this was a seperate discussion I had at some earlier point
with Tim, IRC. I don't think you ever saw this one as it may
have been private email and later irc.)
My argument for why it would be better to make the signal emission
capable of being being completely thread afe has always been
shot down as not necessary because you need to have global locks
for gtk+ any way. If this part comes off of gtk+ then it
will be more of a reason to either remove those parts needing
locks or add locks to those parts. :-) If we are talking about a
general object system to be used in things like sound systems
emits of signals must become something better than a global lock.
(At least from what I would guess.)
> > I personally think that it would be great if the object system
> > and signal system got a good long design review, but I don't think
> > that is possible as no one would ever agree.
> >
> > However, I think this discussion is premature (or grossly too
> > late,) splitting and redesigning the object system from gtk+
> > is really material for 2.0 of the library. In order for
> > it to be usable to the wrappers and ensure flexiblity, we
> > can't just say here is code and use, so elegance of
> > design has to be made. Otherwise you end up in the same situation
> > as today.
> >
> > For example, from the C++ prospective (these cover all of gtk+
> > and some reflect on the object system)
> >
> > - you can't use static cast at all in C++ because the gtk+ object
> > model has no concept of casting to primitive object and use
> > its functions.
>
> Eh? I don't follow. If you map a GtkObject onto a static C++
> heirarchy, then static casts work fine.
> I mean ... certainly if you create a Gtk_Button structure in gtk--
> you can do:
>
> button.add(label)
>
> which is doing implicit static casts...
Static casting to a lower object in C++ means something special.
If I want to call previous implementations of a virtual function
I do...
inside box methods
Gtk_Container::add(w);
or
outside box methods
static_cast<Gtk_Container&>(box).add(w); /* skips Box::add */
We have come to accept this feature as missing as it implies
a lot about the virtual function nature. However, it is a
very good example of where wrapping can never be equal.
> > - The type argument interface is almost worthless as it does
> > not have any way of typesafety, nor can it be easily cast as
> > a stream. (args interface should take float, int, or strings
> > and handle them all instead of casting to what is exected and
> > barfing!) In otherwords be typesafe and if you can't be
> > able to take all inputs and deal with them safely.
>
> Hrmm? I guess you are referring to the varargs interfaces in
> GTK+ ... but those are going to be wrapped anyways by a
> language binding.
[...]
Yes, however, Guillaume has pointed out several places in the
Gnome interface where this was the only way to access something.
Those places give us nightmares and thus we end up rewritting the
whole access functions.
> For the C the typesafe interfaces to argument setting are
> the accessors gtk_container_set_border_width().
>
> Adding something like:
>
> gtk_object_set_int_arg (GtkWidget *widget, char *arg, int value);
>
> would only give you run-time type-safety anyways.
>
> > - there is not way to make a looks/works like something that
> > isn't exactly that type. (poor abstractions) (Okay this
> > is my glist beef and I will carry to my grave.)
>
> No, we aren't going to virtualize GList, sorry. GList is the
> C mapping for the abstract concept of a list of items. Language
> mappings should map GList onto the appriorate list type for
> their language.
>
> > - Too many damn fragments which all have their own reference
> > interface. Why can't they all come from a very simple light
> > interface.
>
> Well, perhaps we can address this somewhat if we create a lightweight
> GObject, but there is definitely a need for even lighter "objects" -
> things that don't present inheritance or virtualization at all.
> (e.g. GString). This was basically the idea of the BOXED type
> that Marius introduced though never fully implemented. That is,
> you have a "object" represented with a pointer, and there are
> two functions that act on
Yes, this is definitely where this discussion is heading. (I
think that is a very good thing.
> > - lack of multiple inheritence. Really it is much more OO to
> > define an interface (which may have some data like a signal)
> > and then have every thing that has that interface inherite from
> > it.
>
> Multiple inheritance is just a complete struggle to implement as
> compared to single inheritance, and doesn't map well onto C.
> Also, there is considerable school of thought out there
> (which I belong to) which says that multiple-inheritance of
> implementation is generally a worse way of doing things than
> aggregation.
I think I have another way to implement it which might be more up
your alley. Unfortunately, it may take some time to bubble up
into an acceptable implementation.
I believer firmly that MI is the best way to do some things in the
interface. For example, a frame may have a "text", a label has a "text",
a menu item has a "text". Therefore the right way to do things
would be to define a text interface, then define an implementation
to draw one, then use those implementations in each of the widgets
so they all share the code, and present the user with the text
interface. Then anything that you can do with a label works
with frames label and so on.
This approach also allows for a work allike, were you take a text
interface and write your own implementation. This is more
like multiple interface.
Of course there is another way to achieve the same effect. That
is just to have only multiple interface that is exportable. Then
the label in the frame is a real label that you export its
interface to the user. (But then what happens when you want
a box instead of a label.)
I think the right solution is to allow for multiple inhertance and
try to make lightweight objects that can be used in composition.
Having said what I think is right I want to state what I
feel is completely wrong. That is the Gtk+ habit of taking
a widget and using parts of the methods while deriving from
it.
IE.
GnomeApp comes from GtkWindow, but it has replaced the contents
so all the GtkWindow methods can't be used. While GtkWindow
is a GtkContainer which can't have multiple contents, so the
add method means totally different things. And the GtkContainer
comes from GtkWidget, but that has special functions for extracting
info which exists in only 3 widgets.... Thus GnomeApp has dozens
of methods that don't belong and are not useful to down right
harmful! Clearly, GnomeApp which decends from IsA window should
have been a HasA window and works like (IsA) a widget.
(C coders don't have much probelm with this other then
it is a pain to newbees. In C++ this is a complete melt
down of the OO system!)
(Hopefully I have done my duty as part of the MI camp and
pointing out the flaws of gtk+.) I know that we are likely on
opposite sides of this issue, but I hope we can agree on
the problems the current system creats.
> Hopefully, by introducing interfaces to GtkObject (as planned
> for 1.4) we'll get most of the advantages of MI without most
> of the complexity.
>
> > - provide hooks to wrappers (meaning the wrappers need to be
> > thought out in advance.) We don't want to have all the overhead of
> > checking and dynamic gtk+ casting all the time because we are a
> > strongly typed language and thus we can give you the exact type needed.
>
> ? There is no need to use the checked casts external to GTK+
> if you don't want to.
>
> Internal to GTK+, yes the overhead will be there (unless the user
> compiled with --disable-debug) ... but if it isn't an issue
> for GTK+ in C, it shouldn't be an issue for C++. If it is an
> issue, than we need to address that for C ... after all, this
> overhead is only sanity checking so if necessary we could
> make --disable-debug the default. (Not that I believe that
> it _is_ an issue.)
OFF TOPIC (for GObject but still relevent to gtk+)
Sorry, I was just spouting off at this point... but you and
I have had discussions before on this with the iterator
concepts for accessing gtk+ list members (not glist). In C++
I have the pointer to the location of a GtkListItem, but I have
to find its number in the list (O(n)) and then pass that to
gtk+ which will go through the list again to find the element O(n),
just to get the current value of a field which I then want to set
which has to do the same thing over again. This is fine if
the list size is 8, but if it is 1000 be have a big overhead.
Now just imagine I was changing some field in every item of the
list that is n/2*4*n => O(n^2)
Gtk+ seems to want to install caches and other such kludges to
turn the number to item pointer. But this just plan doesn't work
for us. It would have been just as simple to define the
procedures to use the pointer to the item and then have wrappers
that use the index number. It would give the same interface to
the user, but much better to wrapper writer. You can still
place the caches but I am sure that users can responsibly use
a GList* to navigate arround.
--Karl
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]