custom functions in introspection typelibs



Hi,

Porting a large app written on gobject-introspection from "old"
gobject-introspection to the latest, I have a number of add-on custom
functions that have to be replaced or kept.

In the long term, we can probably remove the need for any custom
functions, but in the short term we have the idea that gir-repository
allows us to fix any bindings issue without waiting up to 2 years for
new upstream releases to percolate into all the major distributions
(and for users to have upgraded their distribution). Ideally, bindings
can track bleeding-edge gir-repository, and thus put all the special
case workarounds in that common location, instead of having to do it
in each binding. The rule is we need a few-days-turnaround way to work
around any missing API or annotations in upstream libs. This also
means that gir-repository will canonically document the fixes that are
pending for upstream libs.

In most cases there are "correct fixes" that avoid the need for custom
functions, in some cases the correct fix is more g-i capability, in
others the correct fix requires a new upstream release of the
introspected library. I'll append a catalog of custom function
situations.

In the short term, I think it's practical to support a custom
functions mechanism in gobject-introspection.

Thoughts on this:

* my first idea was to build a libgtk-gir-custom or something with its
own typelib, and then in the binding code, manually search both Gtk
and GtkGirCustom typelibs when resolving stuff in Gtk namespace. This
doesn't seem to work because you can't define a method on GtkWidget
except inside the <class name="Widget"> element, so the binding would
have to figure out that a function was really a method, etc. But maybe
we can fix the scanner to be smart enough to generate a second <class
name="Widget"> with methods in it in GtkGirCustom.gir, even though the
main <class name="Widget"> is in Gtk.gir

* second idea is to allow multiple library="" in a typelib. So when
doing dlsym() for Gtk.gir, we'd look in both libgtk and
libgtk-gir-custom. We would scan the header for the custom functions
when creating Gtk.gir. This idea is probably a lot easier to implement
than the first one. The idea here is that the custom functions can be
scanned at the same time as the actual library (we don't need them to
be in a separate typelib).

Possibly related, right now GdkPixbuf.gir creates a "GdkPixbuf"
namespace instead of adding to "Gdk" namespace; this is a similar
extend-an-existing-namespace or
one-namespace-used-in-multiple-typelibs issue.

But maybe thinking about this as a general problem of breaking the
1-to-1 between namespaces and libraries is helpful, I don't know.

Thoughts?

I think my opinion is that we should allow multiple library="" in a typelib.

Havoc

Examples of custom functions:

* custom functions that add accessors, e.g.
gint
clutter_geometry_get_x(ClutterGeometry *geometry)
{
    return geometry->x;
}

Correct fix: add support to gobject-introspection for accessing struct fields.

* custom functions that add boxed constructors, e.g.
ClutterColor*
clutter_color_new (void)
{
    return g_slice_new0(ClutterColor);
}

Correct fix: add support to gobject-introspection for knowing
sizeof(ClutterColor)

* custom functions that do something that's much easier/better in C
than in other languages:

gboolean
clutter_texture_set_from_pixbuf (ClutterTexture *texture,
                                         GdkPixbuf      *pixbuf)
{
    return clutter_texture_set_from_rgb_data (texture,
                                              gdk_pixbuf_get_pixels (pixbuf),
                                              gdk_pixbuf_get_has_alpha (pixbuf),
                                              gdk_pixbuf_get_width (pixbuf),
                                              gdk_pixbuf_get_height (pixbuf),
                                              gdk_pixbuf_get_rowstride (pixbuf),
                                              gdk_pixbuf_get_has_alpha (pixbuf)
                                              ? 4 : 3,
                                              0, NULL);
}

Correct fix: in short term (no new clutter release) I think a custom
function _is_ the correct fix here, because copying the pixbuf pixels
through a higher-level language string object is ridiculous

* custom functions that wrap a macro

gint32
clutter_device_to_units(gint device)
{
    return CLUTTER_UNITS_FROM_DEVICE(device);
}

Another example is GTK_WIDGET_FLAGS()

Correct fix: again in the short term (no new upstream releases),
custom function is the correct fix

* custom functions that register types

GType
g_checksum_type_get_type(void)
{
    static GType etype = 0;

    if (G_UNLIKELY(etype == 0)) {
        static const GEnumValue values[] = {
            { G_CHECKSUM_MD5, "G_CHECKSUM_MD5", "MD5" },
            { G_CHECKSUM_SHA1, "G_CHECKSUM_SHA1", "SHA1" },
            { G_CHECKSUM_SHA256, "G_CHECKSUM_SHA256", "SHA256" },
            { 0, NULL, NULL }
        };
        etype = g_enum_register_static (g_intern_static_string
("GChecksumType"), values);
    }
    return etype;
}

Correct fix: have upstream register the type; but, custom function is
the only possible fix short-term (sub-2-years)


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