Re: [gtk-devel-list] Re: GtkType stuff
- From: Tim Janik <timj gtk org>
- To: gtk-devel-list redhat com
- Subject: Re: [gtk-devel-list] Re: GtkType stuff
- Date: Wed, 9 Sep 1998 00:21:50 +0200 (CEST)
On 7 Sep 1998, Owen Taylor wrote:
>
> Tim Janik <timj@gtk.org> writes:
>
> > On 5 Sep 1998, Marius Vollmer wrote:
> >
> > > Tim Janik <timj@gtk.org> writes:
> > >
> > > > > GtkArgs are used to pass values to signal handlers. Thus, as of now,
> > > > > signal handlers can only have signatures that are expressable with the
> > > > > current GtkArg structure. Thus, there is no signal handler that has
> > > > > arguments with modes that are anything but "in". Because the GtkArg
> > > > > structure can not express other modes.
> > > >
> > > > hm, there at least have been some signal handlers like this, i.e. the
> > > > old GtkWindow::move_resize signal (still in the 1.0.x tree):
> > > > gint (* move_resize) (GtkWindow *window,
> > > > gint *x,
> > > > gint *y,
> > > > gint width,
> > > > gint height);
> > >
> > > Ah, I wasn't aware of this one, but I think there is a
> > > misunderstanding here. I think calling the thing `modes' was a
> > > mistake and I will call them `flow hints' in the sequel. C has modes
> > > and the way I want to define flow hints is not the same as modes in
> > > ADA, or the `var' keyword in Pascal. The flow hints do not talk about
> > > whether we make a new variable when calling a function, or whether we
> > > reuse an existing one, but rather, what a function is allowed to do to
> > > the values that get passed to it.
> > >
> > > Flow `in' means that it is not allowed to mutate that value. This is
> > > different from not being allowed to change the variable (or argument)
> > > that happens to hold this value. It's more like the `const'
> > > qualifier. Actually, it's probably exactly like the `const'
> > > qualifier. Hmm...
> > >
> > > There is no way to mutate an integer, for example. You can't write
> > > something like
> > >
> > > 1 = 2;
> > >
> > > Of course, you can write
> > >
> > > int x = 1, y = 1;
> > > x = 2;
> > >
> > > but that is only changing the object that x denotes. The variable y
> > > is of course unaffected and still has 1 as its value.
> > >
> > > So flow `in' is all that makes sense for integers, and for most of the
> > > other GTK_TYPE_ types defined so far (GTK_TYPE_OBJECT, GTK_TYPE_BOXED
> > > and GTK_TYPE_STRING being the exceptions).
> > >
> > > But you *can* mutate an array.
> > >
> > > int array[1] = { 1 };
> > > int *x = array, *y = array;
> > > x[1] = 2;
> > >
> > > This is actually modifiying the object, not merely making x denote
> > > some other object. Since y denotes the same object, you can observe
> > > the mutation thru y.
> > >
> > > The flow hints are intended to make this propagation of mutations work
> > > efficiently even across language barriers.
> > >
> > > In short, it makes no sense to mark a GTK_TYPE_INT as `flowing out'
> > > because there is no way we could mutate the integer. But we can
> > > mutate arrays, and thus, we should be using them for outward flowing
> > > information, exactly like C does.
>
> My actual opinion is that if we want to go this route, we should go it
> all the way. The argument direction should act as in the CORBA C or
> C++ mapping - in that GTK_TYPE_INT | GTK_ARG_OUT gets mapped as int *,
> while "normal" GTK_TYPE_INT maps as before. Types that are already
> pointers do not get the extra reference.
that's basically what i proposed the GTK_REFERENCE_FLAG on GtkTypes
for.
> Anybody looking at this should definitely look the CORBA
> mapping. The CORBA mapping is rather complex, so we wouldn't
> want to copy it, but some concepts probably carry over.
>
> The way I would do it is that the following get an extra
> reference when passed out or inout:
>
> - Objects that are passed by value in C - ints, floats, etc.
> - Objects that are inherently passed by reference, such as
> GtkObject, or GdkWindow. That is, an out GtkObject is
> passed as an GtkObject **.
>
> While things that are passed by reference in C, but are not
> conceptually always pass-by-reference, such as pointers
> to fixed-length structs, do not get the extra reference.
>
> In fact, there is nothing currently defined in gtk.defs that
> fits into the latter category, but there is a need for such.
> The prime candidate are things like the GtkRequisition argument
> to size_request.
>
> Much more tricky is what to do if we provide some way of passing
> GLists (or GPtrArrays) as signal or function parameters. This is the
> area where the CORBA mapping gets ugly. Probably we should just
> forget the possibility of 'out/inout' GLists.
>
> > > > in general, "in" arguments are always a little questionable for signal
> > >
> > > Don't you mean "out"?
> >
> > of course.
> >
> > > > handlers, because there is 1) no mechanism to check the returned values
> > > > for validity upon every handler invokation, and 2) it is not always clearly
> > > > defined when such modifications will take effect, i.e. does changing a
> > > > value that is passed by reference take effect if modified in an _after
> > > > handler?.
> > >
> > > Yes, agreed.
>
> 1) ???? For a intepreted languaged, the language binding makes sure
> that they are valid, presumably.
>
> 2) There is no problem for something like TYPE_INT. Each handler
> can modify the return value if it so chooses. An OUT value
> of, say, type GTK_TYPE_OBJECT faces the same problem as a return
> value of GTK_TYPE_OBJECT, except in this case we can actually
> solve the problem! We merely need to make the convention
> that before emitting a such a signal, the caller must store
> NULL in the value. And that any handlers that modify the
> value must gtk_object_unref() the existing value if it
> is not NULL.
ok, looks fine to me.
[...]
> > > That's 1.5 bits, but it's of no fundemental importance whether we need
> > > 1 or 2 bits to encode the flow hints, right?
> > >
> > > > for one thing we could, while preserving the current _GtkArg struct
> > > > size, reduce the actuall type information to 31 bits and have
> > > > another one, indicating "inout" behaviour:
> > > >
> > > > struct _GtkArg
> > > > {
> > > > guint type : 31;
> > > > guint is_inout : 1;
> > > > gchar *name;
> > > >
> > > > union {
> > > > [...]
> > > > } d;
> > > > };
> > > >
> > > > but this seems somewhat hackish, and i'm not sure that we do need
> > > > this at all, since the destinction can already be made through the
> > > > fundamental type anyways.
> >
> > > Yes, agreed.
>
> I don't. The direction of the argument is not fixed for a single
> fundemental type, or even a single type. Now if you want to say that
> the type argument to gtk_signal_new is the bitwise or of a type and
> some flags, that might make sense.
again, that's what i suggested GTK_REFERENCE_FLAG for.
[...]
> > some of the above GTK_FLOW_* flags needs to indicate the C language
> > pass-by-reference behaviour, even if you don't intend that as a meaning
> > for the "flow-type" concept. otherwise, we'd be pretty much forced to change
> > all GtkType handling code in existance.
> >
> > > > with this, for the above mentioned ::move_resize signal, you'd actually do:
> > > > gtk_signal_new ("move_resize",
> > > > GTK_RUN_LAST,
> > > > object_class->type,
> > > > GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
> > > > gtk_window_marshal_signal_1,
> > > > GTK_TYPE_BOOL, 4,
> > > > GTK_REFERENCE_TYPE (GTK_TYPE_INT),
> > > > GTK_REFERENCE_TYPE (GTK_TYPE_INT),
> > >
> > > GTK_TYPE_SET_FLOW (gtk_type_get_fvec (GTK_TYPE_INT,
> > > GTK_FLOW_INOUT)),
> >
> > so this would become
> > GTK_TYPE_SET_FLAGS (GTK_TYPE_INT, GTK_FLOW_INOUT),
> > GTK_TYPE_SET_FLAGS (GTK_TYPE_INT, GTK_FLOW_INOUT),
> > [...]
>
> How about simply:
>
> GTK_TYPE_INT | GTK_DIRECTION_INOUT
that was the intention of the GTK_REFERENCE_TYPE() macro, it would
actually be
#define GTK_REFERENCE_TYPE(t) ((t) | GTK_REFERENCE_FLAG)
i think GTK_REFERENCE_FLAG works somewhat better as a name here, since
that actually indicates what we have to care about on the C (and thus:
implementation) side of this stuff.
> > > [ Declarations in header files ]
> > >
> > > > > I think the same, but I don't want to stop at being close. I want to
> > > > > get there.
> > > >
> > > > that's what i intended the comment-enclosed hints for, just like
> > > > owen did for enums.
> > >
> > > Yes, but ommitting these hints would make the system err on the
> > > dangerous side, not on the safe side. When someone writes a new
> > > function and does not provide the necessary hints (because he doesn't
> > > know or care anbout them), we get incorrect behaviour.
> > >
> > > That is, I don't want to have the possibility for introducing bugs by
> > > not knowing about the *.defs system. I can live with incomplete
> > > functionality, tho.
>
> > i'd be interested in hearing owen's comments on this issue, since we
> > seem to be stuck wrt the amount of headaches we want to cause for
> > the intermediate gtk programmer (occasional widget writers).
>
> I don't want to go the route of having GTK+ written in some
> hybrid of scheme and C. If a widget writer doesn't get the
> comment enclosed hints right, then C will still work right,
> it will just happen that language bindings may not. But
> then it is an opportunity for somebody to submit patches.
>
> I think that most C programmers will feel more comfortable with:
>
> GdkWindow* gdk_window_get_pointer (GdkWindow *window,
> gint *x, /*< out >*/
> gint *y, /*< out >*/
> GdkModifierType *mask /*< out >*/);
>
> Then with:
>
> (define-func gdk_window_get_pointer
> GdkWindow window
> ((GdkWindow window)
> (out int x)
> (out int y)
> (out GdkModifierType mask)))
>
> In fact, I'm sure of it.
same here.
>
> Regards,
> Owen
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]