Re: GtkType stuff



On 28 Aug 1998, Marius Vollmer wrote:

> Ok, on with it.
> 
> Tim Janik <timj@gtk.org> writes:
> 
> > > * Modes
> > > 
> > > We need to deal with `pass by reference'.  I'd like to add modes to
> > > argument specifications (and also to values when they are used as
> > > arguments in the signal system (I'think I'm a bit confusing here)).
> > > Mode `in' is what we have now, modes `inout' and `out' are the obvious
> > > extensions.  I want to allow outward modes only for composite types so
> > > that the calling conventions are completely unaffected by the mode of
> > > an argument.  The typical case of
> > > 
> > >     void foo (int *x_ret);
> > > 
> > > would have to be declared as a function taking a vector of fixed
> > > length 1 with content type "int" and mode `out' (or `inout').
> > 
> > again, i'm not sure on how you intend to fit this into the actual
> > type system. at least for the GtkArg functions, the in/out behaviour
> > it pretty much defined.
> 
> To what functions are you referring exactly?  I assume gtk_object_get,
> get_object_set and GTK_ARG_READABLE, GTK_ARG_WRITABLE, etc.
> 
> If I understand them correctly, they refer to the properties of the
> `object arguments'.  Whether they can be read, written, and other
> stuff.  Right?

yeppers.

> This is similar too but not the same as what I want to have modes for.
> This is more of an issue for the static side of the type system.  We
> need to describe function signatures, and pass by reference is a
> useful technique that needs to be covered by these descriptions.

but this is independant of the existing argument system.

> This is somewhat independent from the dynamic side of the type system.
> The dynamic side should mirror the static side as close as possible,
> but it need not include everything.
> 
> So the first thing is to have modes for the formal arguments of
> functions.  An example: the function
> 
>     void foo (int x);
> 
> would be described within the static side of the Gtk type system as
> (in gtk.defs notation):
> 
>     (define-func foo
>       none
>       ((int x (mode in))))
> 
> where `(mode in)' is the default and can be left out.  Mode "in" means
> that the function foo is not allowed to change the value of x.  Mode
> "out" means that it is allowed to do so, but it shouldn't expect any
> useful initial value.  Mode "inout" is the logical combination.
> 
> Now, one might want this description
> 
>     (define-func foo
>       none
>       ((int x (mode out))))
> 
> to correspond to
> 
>     void foo (int *x);
> 
> But I don't want to make the mapping between Gtk type system types and
> C types dependent on the mode.  Rather, a mode other than "in" is only
> meaningful for composite type because those types represent values
> that can be mutated.  So the right description would be
> 
>     (define-func foo
>       none
>       (((vec int 1) x (mode out))))
> 
> Another way to see these modes that might make more sense: they are
> just hints for potential optimizations.  Think about a binding that
> has to explicitely convert between its own representation of vectors
> and the C representation.  To be right, it would have to convert from
> its representation to the C one when calling a function, and would
> have to convert back when the function has returned.  The mode hint
> allows us to drop one of these conversions (which might be costly
> indeed).
> 
> Now, I'm not too sure how to get this into the run-time side of the
> type system.  Maybe a new field in GtkArg.

erm, this has nothing to do with the GtkArg structure. GtkArgs are used
for signals and the argument system. as you stated above, the information
is needed on linkage time and does not interfere with the dynamic type
stuff.
so why would you want to have information like that in GtkArg?
also, i'd like to keep the GtkArg structure as small as possible, since
gui builders and eventually some langueage bindings make extensive use
of it.

> An open issue is what to do about aliasing.  If we have a funtion with
> two outward arguments, and specify the same composite value for both
> of them, what is the language binding required to do in this case?
> 
> [ Declarations in header files ]
> 
> > we had that for enums and flags already, some time ago, and it didn't 
> > find the widest acceptance for most people, that's why owen jumped
> > in and created the above mentioned perl script.
> 
> I see.  But I don't particularily like the guessing of the prefix.  I
> have to admit that I don't fully understand what's going on in the
> Perl script, so I have to look closer.
> 
> > a bunch of the gtk functions should really be easy to convert into an
> > appriopriate .defs file format, using a smart prototype parser.
> 
> My stance on this is that it is not possible to do this reliably.
> That's actually the point of this while gtk.defs business: to provide
> *more* information than is evident from the header files.  Just
> guessing, well a "char*" is like a "string" is not good enough.
> That's also where "char" breaks down: what's it, a character or a
> small integer?

the perl script for enum extraction uses some speciall magics encoded in
C comments for some special cases, maybe something similar to that would
be sufficient for functions that don't map directly into a .defs file.

i'd guess that some simple rules would basically do the trick for the
in/out stuff, e.g. return values are always out, with char* being
considered as dynamically allocated by default. similar rules would apply
for the function arguments, e.g. "int", "float" and "char*" are considered
`in' parameters and "int*", "float*" and "char**" are considered `out'.
so we eventually get something like

void       gtk_widget_set_name            (GtkWidget           *widget,
                                           const gchar         *name);
/*< DEFUN (gtk_widget_get_name (string) ((GtkWidget*widget))) >*/ 
gchar*     gtk_widget_get_name            (GtkWidget           *widget);
void       gtk_widget_set_state           (GtkWidget           *widget,
                                           GtkStateType         state);

to override the default description, which would have been

(define-func gtk_widget_get_name
  (string (mode dynamic-alloc))
  ((GtkWidget *widget)))

the returned string would be (mode out) by definition and the associated
widget would be (mode in) by default, so i omitted these two flags.
the other two functions don't need special casing, since the above mentioned
rules for default .defs generation would be sufficient, i.e.

(define-func gtk_widget_set_name
  none
  ((GtkWidget *widget (mode in))))
(define-func gtk_widget_set_state
  none
  ((GtkStateType state (mode in))))


> > the results could then be adapted for some functions that need special
> > casing.
> 
> Hmm, too tricky, in my view.  The default should be safe.  So when you
> do not specifically declare a function to be fit for gtk.defs it
> shouldn't be included, IMO.

i don't think this scheme is too tricky, and it has been sufficient for
at least the enums ;)
i think we can get close to the matching-rate for enums with the function
definitions as well, if we come up with smart defaults for the .defs
generator.

> > also, not all widget writers are aware of the usage and means of the
> > .defs file formats, requiring them to put GTK_DEFFUNC() macros into
> > the header would but a burden on them that is, imho, unjustified.
> 
> When they don't know how to do it, then their functions shouldn't be
> described in gtk.defs.  Yes, you actually have to take a bunch of
> maybe non-obvious things into consideration when writing the *.defs
> stuff, and it is a burden.  But I dont't think that convenience is a
> good enough reason to be sloppy here.  The *.defs file must be precise
> and it must be right.  That's its sole purpose.
> 
> 

---
ciaoTJ



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