[Geany-Devel] New plugin loader mechanisms

Matthew Brush mbrush at xxxxx
Thu Mar 19 00:19:44 UTC 2015

On 15-03-18 03:55 PM, Thomas Martitz wrote:
> Am 18.03.2015 um 23:21 schrieb Matthew Brush:
>> On 15-03-18 03:05 PM, Thomas Martitz wrote:
>>> Am 18.03.2015 um 22:15 schrieb Matthew Brush:
>>>>>> [...]
>>>>>> void (*init) (GeanyPlugin *plugin, gpointer pdata);
>>>>> Please make this gboolean. A plugin may have the correct API and ABI,
>>>>> but be unable to startup / initialize for some reason. For example,
>>>>> Scope requires scope.glade in the plugin data directory).
>>> Thinking about it, if the plugin can't run because it's missing resource
>>> files required for its operation, then I think it should be treaded like
>>> incompatible plugins. This has the benefit that they will be attempted
>>> to be loaded on the next startup if the user had previously selected it.
>> For resource files like say a GtkBuilder UI file, I'd agree, but there
>> may be some other cases, for example if a plugin dynamically loaded
>> some particular library (or variant of a library) based on user
>> configuration, it'd be useful to report to the user that the library
>> is wrong, or no longer available, or whatever.
> Based on user configuration implies that it's a decision that is made
> after the plugin's init(). If it allows the user to configure it without
> this dependency then the plugin is considered operational, and init()
> should not fail. Remember that a init() == FALSE would imply that the
> plugin cannot be activated, and therefore not configured (i.e. you
> cannot configure back so that it doesn't need the missing dependency).
> Such custom requirements & errors are better placed in the plugin code
> itself.
>>> I'm thinking if the plugin loaded successfully, then it should be
>>> operational too. Meaning that init() should not fail, but simply
>>> activate the plugin. As outlined above, my proposal already covers the
>>> case "compatible but not operational due to missing runtime
>>> dependencies" you described.
>> For cases like GeanyPy which loads arbitrary Python scripts (which are
>> even fully executed on import), and in a language where Exceptions are
>> common (especially during development), it would probably be useful to
>> signal that the plugin script couldn't be loaded and maybe even be
>> able to provide a formatted traceback of the Python exception or such.
> In my roadmap geanypy does not load scripts in its init(), but through a
> separate API (so that the scripts integrate into the main plugin
> manager). Anyway, geanypy init() isn't the right place because geanypy
> can load multiple scripts, and which scripts can change afterwards after
> init has run. And finally, all those scripts do not change the fact that
> geanypy itself is operational, and this is what we're talking about.

I think I misunderstood the purpose of your `init()` function. I thought 
it was a hook to allow the plugin manager/geany to be able to initialize 
multiple plugins from the same .dll/module (ex. sub-plugins, etc). If 
that's not the case, isn't the `init()` pointer in the struct basically 
redundant as plugins could do their initialization in the roughly 
equivalent `geany_load_module()` that is also called once per .dll?

For that matter, why not just leave the hooks all as loose functions (as 
opposed to set into a structure), and just fix the prototypes to pass 
around GeanyPlugin* and/or user_data, or whatever improvements? AFAIK 
there's no issue with symbols/collisions if Geany just uses RTLD_LOCAL 
when dlopen-ing the plugin module.

Matthew Brush

More information about the Devel mailing list