Re: [Vala] Impossible to subclass from gio stream classes?



On Wed, 2009-09-30 at 19:46 +0200, Jan Hudec wrote:
On Wed, Sep 30, 2009 at 18:58:54 +0200, Philipp Zabel wrote:
I'd like to subclass GLib.BufferedInputStream.
Vala doesn't like the following construct:

class MyStream : GLib.BufferedInputStream {
    MyStream (GLib.InputStream base_stream) {
        base (base_stream);
    }
}

$ valac mystream.vala --pkg gio-2.0
mystream.vala:3.3-3.20: error: chain up to
`GLib.BufferedInputStream..new' not supported
        base (base_stream);
        ^^^^^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)

Am I doing it wrong? BufferedInputStream has a constructor that takes
one GLib.InputStream.

Short story:
------------

    MyStream (GLib.InputStream _base_stream) {
      base_stream = _base_stream;
    }

Long story:
-----------

The thing with constructors in vala is a bit complicated, because the GObject
type system is a bit strange. They are not really to blame, they did it for
convenience of use from C.

The "constructor" you see is so called construction method. It allocates and
initializes the object in one operation, so it cannot be used for allocating
a subclass.

For vala defined classes, the compiler generates an additional function for
each construction method, that takes id of the type to allocate as additional
parameter, so it can be used for the constructor chaining, but the classes in
glib don't have such functions.

However, each GObject-derived class can be allocated without using the new or
construct function and in fact it is how the construct function eventually
allocates the object -- via g_object_new. That will gather all construct
properties and call an instance_init function for the object.

The GLib.BufferedInputStream class inherits a construct-only property
"base-stream" (written with underscore as identifier) from it's
GLib.FilteredInputStream base class. The construction method just sets that
property and invokes the object allocator. You just need to do the same.

Note, that in your class, you can have a 'construct { ... }' block. The code
there is placed into the init_instance, which makes it called as part of
every construction method. It will be called even if your object gets
manually constructed by GLib.Object.new, in which case none of the
construction methods will.

Wow .. that hurts !
Does that mean that sbuclassing a non-Vala GObject is different from
subclassing a Vala one ?
Is there a wiki page describing this clearly for simple minds like me ?

Thanks,
        Xav






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