[Vala] wrapping structs / wrapping vapi classes



These suggested changes would permit vapi files to wrap structs that contained a virtual method table. If they are not objectionable to the development of Vala, I intend to provide patches.

I like how vapi classes can wrap structs as classes; I'm investigating how these can be almost first-class classes, especially in the case where the struct contains function pointers, effectively a virtual method table.

Vala implements calling virtual methods with a wrapper like this:

struct _youngerClass {
       olderClass parent_class;
       gint (*use_the_internet) (younger* self);
};
...
gint younger_use_the_internet (younger* self) {
       return YOUNGER_GET_CLASS (self)->use_the_internet (self);
}

It seems like the line:
return YOUNGER_GET_CLASS (self)->use_the_internet (self);

Could be replaced with:
return YOUNGER_GET_VMT (self)->use_the_internet (self);

where  in most cases
#define YOUNGER_GET_VMT YOUNGER_GET_CLASS

but this can be overridden in the VAPI file, maybe with vmt_expression=".."

For samba4 ntvfs struct it would become
#define YOUNGER_GET_VMT(self) self->ops

so that the expanded code becomes
return self->ops->use_the_internet (self);

which would be spot on

However we need to convince vapi files to permit virtual methods too; this vapi:

namespace Ntvfs {
[CCode (cname = "struct ntvfs_module_context", cprefix = "", free_function = "talloc_free", create_function="xx", ref_function = "talloc_reference", unref_function = "talloc_free" vmt_expression="self->ops")]
       public class Ntvfs {
               public virtual int something_virtual();
       }
}

does nothing with regard to "virtual" and calls in a subclass (or anything) to something_virtual are left as calls to cprefix . "something_virtual" but I think it should render to: "self->ops->" . cprefix . "something_virtual(self)" (where the position of self depends on instancepos and all that stuff as it currently does).

It would likewise be possible to override such methods, in the instead of this in the subclass _class_init: NTVFS_CLASS (klass)->something_virtual = subclass_real_something_virtual;
have this in the _instance_init
YOUNGER_GET_VMT(self)->something_virtual = subclass_real_something_virtual;

So I guess we would need a CCode directive to indicate if the vmt was per-class or per-instance.

Are these objectionable to the direction of Vala?
I would do something likewise for properties so they could be mapped to the members or expressions of the struct instance.

Later, I also want to add C (or vala? - probably not) code blocks to vapi files which would be treated as inline methods (!!) to the caller, this can encapsulate special construction steps or other massaging which is not in the wrapped library but which ought to be done.

Sam





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