Re: [Vala] Chaining up constructors.



Hello Yu,

On Fri, 2008-11-21 at 21:27 -0500, Yu Feng wrote:
Dear Jurg and others,

I have an idea about chaining up constructors to share with you.

Situation
========
We have 2 different constructors, the construction block(CB), and the
construct function(CF).

for GType based classes, CB doesn't work, chaining up CF works.
for GObject based classes, CB works, chaining up CF doesn't.

We also have construct properties(CP); CF can and should initialize CPs,
CB can not and should not.

Whenever there is a CF, two CCode functions are generated: _construct
and _new. For CB, _constructor is generated.

The memory allocation is done in _construct.

New Idea
=======

The basic idea is to move memory allocation to _new functions, and let
_construct functions initialize the properties. It is then much easier
to chain up the _construct functions without worrying about memory
issues. The other idea is to manifestly invoke '_constructor' for GType
based classes. 

With these two changes, we can arrive the maxium symmetry between
GObject classes and GType classes. It also permits one to freely switch
the base type of any classes between GLib.Object and nothing without the
need of modifying any code.

I have to agree, I'm a bit confused with the current situation. As I
understand it, please correct me if I'm wrong; you now have two options
for GObject based construction.

(1) You either use the classical GObject construction scheme with a
registered constructor function (the construct block) and GObject
(construct) properties as parameters. You need [CCode
(has_construct_function = false)] for your creation methods if you only
want use this.

(2) You use the new chaining constructor functions, which are the
default and not limited to the classical construction scheme
requirements. They do break the classical GObject construction outside
vala, so you probably need watch out with this when these objects are
only created with g_object_new somewhere. You can still use a construct
{} block. But these blocks are triggered and chained in the g_object_new
call, so they don't always make much sense when using custom chained
constructors.

But then again, if you use the new scheme, you can freely switch your
base class to a fundamental class or a gobject one without having to
change anything. This also implies that I could do something like bellow
which is not possible with the classical GObject construction scheme:

public class Foo: Object {
        private string data;
        public Foo (string data) {
                this.data = data;
                stdout.printf ("Foo::data %s\n", data);
        }
}

public class Bar: Foo {
        public Bar () {
                base ("John Doe");
        }
}

public class Maman: Bar {
}

Of course, when this is not the intentional behaviour and my assumptions
are wrong, we should probably fix this as soon as possible! Because I'm
sure that a lot of people that are not familiar with GObject are going
to use it this way.

For GObject based classes:
-----------------------
1. for each CF, generate a _new function,
Object _new(param1, param2, param3...) {
int n_params;
GParameter * params = _construct(&n_params, param1, ....);
return g_object_newv(TYPE, n_params, params);
}

2. for each CF, generate a _construct function,
GParameter * _construct(&n_params, param1, param2, param3) {
      translate all the logic in CF, if there is an assignment to a property
with getter and setter, create the correspoding GParameter
        chain up is also done here by merging the return value of the
parent's _construct function.
}

3. for each CB, generate the _constructor function, and hook it to the
GObject class structure.

I don't think you should mix the two construction schemes to much as
they are essentially incompatible. GObject basically doesn't support
custom constructor chaining interference, so if vala wants to support
this (and by doing so breaking the GObject way a bit), why keep the
property assignment limitation?
As a consequence, I also consider it to be a great performance
enhancement not having to use GParameters and construct properties. The
GObject constructor function only takes construct properties, the others
are filtered out in the gobject core. So I think you would have to use
construct properties by default in this case, which again is very slow.

Regards,
Hans





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