Moved from: Strawman: Move GType down to libglib-2.0.so (#2370) · Issues · GNOME / GLib · GitLab
The type system is not a huge amount of code, and there’s no real need why it should live in libgobject, when a good chunk of types exposed by GLib are boxed in there.
In practical terms, the type system is just a low level API not dissimilar from GVariant. My proposal is to literally move the existing GType and GValue API down one level, with no ABI/API changes; this would allow us to use the type system for the GLib data types out of the box, as well as adding type specialisation to the opaque data containers. We could even add API to GArray/GPtrArray to properly store typed data, and finally replace GValueArray.
The main objection from existing consumers of GLib is that GObject strings along a bunch of additional functionality—signals and properties, closures, etc. We can easily keep those into libgobject-2.0.so; I’d actually insist in keeping them isolated in libgobject, in case we decide to create a new base object class that does not have the known issues of GObject.
The complexity of this surgery is mostly limited to:
- moving existing GObject/GClosure/GParamSpec initialisers to their own file from gtype-private.h and gtype.c
- moving gtype.[ch] and gvalue.[ch] and ancillary private files from gobject to glib
- ensuring that the type system is initialised alongside GLib
- ensuring that the GObject ancillary types are initialised
Use cases
It’s a big problem we have in GStreamer since the deprecation of
GValueArray
so any improvement here
would be useful. The basic issue is that some kind of “GArray of GValues” type is needed where it can be known
from the type that it containsGValue
s, without any secondary, external metadata like annotations.I assume what @ebassi wants to do here is adding a
GType
toGArray
andGPtrArray
so the
element type can be known at runtime.
Adding GType/GValue-based API to GArray, GList, GHashTable, and other data containers without duplicating their internals inside libgobject.
This would also simplify the issue of bindings being unable to deal with transfer rules for data inside container types that have a “clear” function, as the memory management would then be deferred to GType/GValue, just like they are for GObject properties and signal marshallers.
Potential issues
While I think that would be great, I worry about the users of GLib who don’t use GObject. Are you envisaging that they would be able to use
GPtrArray
(etc.) as before, without type annotations?
They would still not use GObject. To be clear: I’m not suggesting we move GObject
to libglib-2.0
: only GType
and GTypeInstance
. The type system by itself isn’t a huge deal; it wouldn’t be problematic for people using only the GLib data structures.
Also, and to be quite blunt: it’s 2021. The objections on the basis of code size made sense 20 years ago, but just like the requirement to use modern toolchains, I find myself struggling to care about people using GLib like it’s 1997, and they only need a bunch of C data types.
Are you envisaging that they would be able to use
GPtrArray
(etc.) as before, without type annotations?
Yes. I mean: this is an API addition to libglib-2.0.so
.
We could then add API to our void*
containers to box/unbox the data into GValue
, or to specify the GType of the elements, without having to create a GTypeArray
, a GTypePtrArray
, or a GTypeHashTable
inside libgobject
.
Comments
I misspoke and should have said GType
in my comment, not GObject, sorry.
The type system by itself isn’t a huge deal; it wouldn’t be problematic for people using only the GLib data structures.
I think it would be a bit of a deal if they were not using GType
already, and then this change forced them to use, or integrate with, GType
. We can design this so that doesn’t have to be the case, though.
Also, and to be quite blunt: it’s 2021. The objections on the basis of code size made sense 20 years ago, but just like the requirement to use modern toolchains,
I actually had more in mind the path dependency of projects which chose to use GLib (but not GObject) many years ago, and for whom changing to do anything else would be a lot of busy-work.
If we’re talking about best practice for projects in 2021, it would be to not use C at all, in the general case.
I find myself struggling to care about people using GLib like it’s 1997, and they only need a bunch of C data types.
Be nice.
We could then add API to our
void*
containers to box/unbox the data intoGValue
, or to specify the GType of the elements, without having to create aGTypeArray
, aGTypePtrArray
, or aGTypeHashTable
insidelibgobject
.
A rough strawman of these APIs would be helpful.
I’d actually insist in keeping them isolated in libgobject, in case we decide to create a new base object class that does not have the known issues of
GObject
… or just a better property or signal mechanism. I agree that this shouldn’t be in GLib in this form.
moving
gtype.[ch]
andgvalue.[ch]
and ancillary private files fromgobject
toglib
How would that work with G_TYPE_OBJECT
? Would that move as constant into GLib nonetheless?
And I assume interfaces would move to GLib completely together GTypeClass
and GTypeInstance
and all the corresponding machinery?
G_TYPE_OBJECT
is just a fundamental type, so it can live inside libgobject, just like any other fundamental type inheriting from GTypeInstance
does.
And I assume interfaces would move to GLib completely together
GTypeClass
andGTypeInstance
and all the corresponding machinery?
Yes: GTypeClass
, GTypeInstance
, GTypeInterface
, and GTypePlugin
would move down one level. The latter is just an interface, so it does not have any further dependency, but the code inside GType
checks for it when trying to gather type information.
Can we leave the plugin functionality behind ? I think that would be a nice win
We still need GTypePlugin
around because it’s exposed in the GType API. The good news is that it’s just an interface, so it doesn’t do much by itself: you need to implement GTypeModule
, which will automatically implement GTypePlugin
. I don’t plan to move GTypeModule
in libglib-2.0, mostly because it would require bringing GObject and GModule down one level.