Re: Bikeshedding the gnome-class mini-language



On Wed, 2017-10-25 at 10:41 +0200, Sebastian Dröge wrote:

How about (public) fields in classes though? Those allow to do some
degree of meta-programming with GObject and we use that in GStreamer
(and GObject also uses that, e.g. properties).

Could you point me to a place in GStreamer that uses this?

With the "impl GObject for MyClass" thing, I was thinking of putting
the GTypeInfo's base_init, base_finalize, class_init, class_finalize
functions there.  I feel like this is related to public fields in
classes, but I'm not completely sure.

Vala supports some funny flags for constructors - https://wiki.gnome.or
g/Projects/Vala/Manual/Classes#Construction - which may be related to
those, too.  I'll have to look at the code that Vala generates.

(... aren't public class fields just as problematic as instance fields
ABI-wise?  Or is this so that type plugins can provide "global
variables" in a sane way?)

[reserve_slots(N) for ABI]
Much nicer, yes. In GStreamer we just use a
  gpointer _padding[GST_PADDING-X];

Nice, so there is a clear need for this.  I'll put it in.

Everything in instance_init() is already initialized (to all-zeroes).
But I was more thinking of calling functions of the subclass. E.g. in
GStreamer you usually set up static pads in there.

I've just read a bit of gobject.c to really see the initialization
sequence.

- gathers construct properties (*)

- calls ::constructor() with the construct properties, which chains
up...

- ... until it reaches the topmost g_object_constructor(), which...

- allocates memory for the instance...

- calls ::init() on each superclass...

- calls ::set_property() just for the construct properties...

- ... and then the rest of your ::constructor() runs.  But apparently
if you don't chain up, you can use this to implement singletons?  Do
you know of a place where this may be used?

- calls ::constructed()

- calls ::set_property() for the non-construct properties.

(*) Until now I didn't realize that a GParamSpec's default value only
gets used if the property in question is a construct property.  Is this
correct?  I had assumed that *all* declared properties were used, and
the ones not specified by the caller got their default values.

Also, I used to think that ::constructor() was responsible for directly
using the construct_params that it gets passed, but they are just to
call the parent class constructor.  (I wouldn't be surprised if some
silly object actually frobs those values before passing them on, but
jeez.)

From my reading of this, everything until ::constructed() is called
means that the instance is only halfway-initialized.  At ::init() it is
"basically uninitialized memory, actually zeros"; after chaining up in
::constructor() it is "the bare minimum properties have been set"; and
only in ::constructed() is it "minimum initialization is complete; all
extra properties are sugar on top".

Therefore, in general I don't think code should call methods during
::init() - whether it actually works will of course depend on the code
in question :)  I do remember having bugs with this in the past ("no
wonder the method fails; the object is not fully initialized yet").

As a thought exercise, could GStreamer set up those static pads in
::constructor() or ::constructed() or something?

["override Superclass for Foo"]
"impl SuperClass for Foo" would be nicer IMHO.

Yeah, I agree.  Noted.

  #[attributes...]
  property some_property: u32 {
    get(&self) -> u32 {
      self.something
    }
    set(&self, value: u32) {
      self.something = value;
    }    
  }
}

Maybe? Not sure about providing the type 3 times, but this way seems
most consistent.

Makes sense.  I'll look more closely at Vala.  From it and from C# I
don't like the magic "value" that it uses inside setters; it appears to
come from nowhere.

Would "_" make sense just avoid repeating the type?

property some_property: u32 {
    get(&self) -> _ {
        self.private().foo
    }
    set(&self, value: _) {
        self.private().foo = value;
    }
}

[signal accumulators]
I meant examples where they're used in GStreamer :) Code-wise it's
all simple really.

Thanks for the explanation.  I already noted your 
"#[accumulator(my_fn)]" idea.


This is very cool stuff.  I feel a lot more comfortable with the syntax
now; it looks like it's going to be more extensible like that.  Thanks
for all the suggestions :)

At the end of this file is the proposed syntax, with your updates (grep for "New syntax"):

https://raw.githubusercontent.com/federicomenaquintero/gnome-class/master/gobject-notes/notes.txt

I'll probably convert that from org-mode to Markdown so github can format it...

  Federico


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