[Geany-devel] GObject, new plugin interface ....
Matthew Brush
mbrush at xxxxx
Thu Mar 17 06:56:05 UTC 2011
On 03/16/11 22:25, Lex Trotman wrote:
> Hi Matthew and All,
>
> @Matthew, I've looked at your dbus repo. I might not have understood
> how you were relating it to this, but to me it looks like you are just
> using the old plugin interface, rather than anything to do with a new
> interface.
It's very bare still, but there are some things going on which fall into
line with the GObject interface. The only real reason it's been
referred to is that it 1) provides a GObject wrapper/C API around the
current plugin API emitting signals from the right objects, using real
properties, etc, 2) (will) provide a shared library that
bindings/clients can link to, and 3) provides process isolation. Other
than those ideas it's so incomplete/new as to not be too relevant. I'm
actually not really planning on working on it until after there's a new
GObject interface to Geany, since afterwards, it would be just a matter
of inheriting from a few classes and tacking on GDBus stuff.
Unfortunately, there is some context around this which has been
discussed around the geany-vala-binding, that a lot of which wasn't on a
ML. It's very easy to summarize some of the ideas I've had/heard so far:
- The geany-vala-binding should be sort of a "raw" wrapper around
the existing plugin API, providing simple access from Vala code.
- There needs to be a GObject wrapper around a lot of the
existing stuff where it makes sense, since a lot of it is
sorta OOP in design. This could use Vala to generate all of
necessary boiler-plate GObject C code and allow doing things
like ABCs and interfaces without gobs of (hand-written) code.
- Signals for the plugins need to be emitted from the
appropriate objects. rather than the current central
GeanyGObject which is has all the signals. An example would
be that the "saved" signal should be on a Document object.
- The API should enforce read/write access on the objects
via properties/accessors. The current API just exposes raw
struct members, certain ones which, when set would result
in strange behaviour in Geany. The current API does have some
getters/and setters though they aren't really consistent. For
an example of how the Vala binding is wrapping this
inconsistent access, see [1]. The point of the DBus binding
directly wrapping the Vala binding was to make it a true
GObject API, where the Vala binding just provides a window to
the existing raw C code (more or less).
- Libpeas[2] should be used as the actual plugin finder/loader. It's
a GObject/GLib library designed specifically for finding plugins
in different languages, loading their interpreter, and doing
stuff like activation/deactivation. It seems Gedit is using this
as well as several other popular GNOME-ish programs.
- There is a huge namespace clash with the current plugin API, in
order to use sensible prefixes and class names. Nothing in the
new interface can be prefixed with Geany, geany or GEANY, which
of course would be the sensible prefix for an API. The new
interface would have to use something like GeanyLib or LibGeany
or whatever, and then in the language bindings the namespace
could be whatever (except in Vala where there will still be
collisions).
I think that roughly sums up the discussion I've heard so far that may
or may not have been on this ML.
Why all the discussion around Vala[3]? It's just *really* nice for
generating GObject C APIs, like GOB2 on steroids. It can output C files
so that users are not require to have the valac compiler installed, it
also can output C header that can be installed like headers are with any
other library for use by C code. My personal opinion is that it would
be ideal to use Vala for the new GObject interface, at the very least to
get something working, and then possibly port it bit by bit into
hand-crafted C (though valac's C is pretty clean considering).
>
> @All,
>
> Having reviewed what has been said in the thread to date, there is no
> real substance, so I think its likely that we may be talking about
> subtly different things. So to start the ball rolling here is an
> initial description of what I understand as the aims of this work and
> how I see it possibly being implemented.
>
> As I see it the purpose is to define a new plugin interface to Geany
> that exposes all the required machinery through a set of GObjects
> which can be (semi) automatically interfaced to languages other than
> C, allowing Geany to have plugins written in multiple languages.
Using GObject-introspection hopefully in most places[4].
> This new interface should provide at least the capabilities of the
> current plugin interface.
Agreed.
> The way I see it being implemented, is not to change Geany's existing
> C structures into GObjects, rather, that the GObjects provide an
> interface to the existing C implementation and may not even map one to
> one with the existing structures.
This is in line with the previous discussions, especially the
geany-vala-binding providing Vala access for the GObject wrappers to
use. I agree that in quite a few cases it won't (or shouldn't) map 1:1
with the old API.
> This has several advantages,
>
> 1. the interface is somewhat isolated from the Geany implementation,
> allowing the implementation to evolve without causing a change in the
> interface seen by plugins. The current plugin interface is so thin
> that it is easy for changes to Geany to affect the interface.
> 2. the impact on the core implementation is minimised, so the impact
> on anything else happening in Geany itself is smaller.
> 3. The interface can be defined such that it is easy for plugins to
> use, independent of the underlying implementation
I studied the code in documents.{c,h} a bit just to see what it would
take to convert a GeanyDocument into a GObject. My observations were
that it would a) require an almost complete re-write of that code, b)
completely mess with the existing plugin API as well as tons of stuff in
the core that uses GeanyDocument's and c) that it would bloat the code
up so much that I don't think it would fit with Geany's "fast and light"
philosophy. So your #2 point is really important I think.
> I see the GObjects as simply containing pointers to one or more of the
> Geany structures and the methods each being just a few calls to
> existing functions that operate on these structures.
Yep, and wrapping them up in GObject properties and signals so Gobject
introspection can do its magic in making the higher level language
bindings idiomatic (or I guess OOP-ish, since it's roughly the same in
most languages I know).
> There will still need to be code added to the existing implementation
> since it needs to create and destroy the GObjects as required and will
> have to emit signals on them when required. But this is a much less
My initial though was a regular old Geany plugin, using the Vala binding
and Vala output C API to provide the "glue" without even touching the
existing core code directly. This would at least provide a nice
testbed. Then the existing plugin API could just have the odd struct
tweaked or function added, etc.
> intrusive change compared to re-implementing core in GObjects. In
> fact it should be only additional code (albeit intertwined in the
> existing source), so minimising the likelihood of bugs being
> introduced into the existing Geany functionality.
Very important indeed.
> Since the purpose is to support multiple languages, I think that some
> support for initialising and sharing interpretors/runtimes also needs
> to be created. It doesn't help someone to write Python or C# plugins
> if they have to figure out how to interface the Python interpretor or
> Mono runtime first. That should be done once for each language and be
> a loadable part of Geany. This process should also know how to find
> the plugins in the particular language, like Java ones in jar files,
> Python ones in directories with __init__.py in them etc. Sharing is
> needed to reduce the bloat that would occur if each plugin had to have
> a copy of the interpretor/runtime code
This is exactly where LibPeas[2] fits in. I've not found anything that
would fit the bill as well as LibPeas would. Also, if we were to add
interpreter/runtime loaders to LibPeas, the benefits would populate
across to other important projects like Totem, Gedit, Eog, etc. and of
course vice versa. Currently LibPeas only has plugin loaders for C (so
probably Vala and Genie as well), Python and JS, but surely more can and
will be added in the future.
> Hope this gives something to think about and throw things at.
Thanks for getting the ball rolling, I'm anxious to hear what others
have to say.
[1]
http://gitorious.org/geany-vala-binding/geany-vala-binding/blobs/master/geany.vapi#line902
[2] http://library.gnome.org/devel/libpeas/0.7/
[3] http://live.gnome.org/Vala/Tutorial
[4] http://live.gnome.org/GObjectIntrospection
Cheers,
Matthew Brush
More information about the Devel
mailing list