Am 30.03.2015 um 23:07 schrieb Thomas Martitz:
Am 30.03.2015 um 14:57 schrieb Colomban Wendling:
If `pdata` is provided in geany_plugin_register(), how does it get
released? If it has to be a pointer to static data it's a bit limiting,
and forces use of (static) globals, which is one thing that this new API
tries to avoid, doesn't it? We could also ask for a GDestroyNotify, but
that's an additional arg we might not need.
And also, providing the pdata in geany_load_module() might mean memory
allocation, allocation that might never be used if the plugin isn't
activated.
OTOH, if `pdata` is a member of GeanyPlugin, it can be allocated in
init() and freed in cleanup() without having to tell Geany how it has to
free it.
I see what you mean. Indeed, this could be a problem.
I wanted the pdata parameter such that it is friendly to language
bindings. This doesn't work if the user_data is hidden down in some
other structs passed as parameter. For example, I wanted to make it
possible to use vala member functions classes directly as plugin
hooks. And this works, however there is indeed a leak. I have a
prototype, see below.
Considering this use case I would rather take the GDestroyNotify than
hiding down pdata in another param. Passing it to
geany_plugin_register() also allows for using a member function for
the init() hook already.
What do you think?
Replying to self after having thought about it a bit more.
Since I do want to maintain the ability to set the data in
geany_load_module(), or rather just before the plugin's init() (to
enable the use case cited below), but also at the same time still allow
it to be also set in the plugin's init() (some plugins don't want
expensive allocs before init()) AND definitely pass the pointer as a
separate parameter, the only think I came up with is a separate API
function to set the data, including the destroy notify. So I have now:
geany_plugin_register(GeanyPlugin *, gint api, gint min_api, gint abi,
GeanyPluginHooks *); /* pdata param is removed */
geany_plugin_set_data(GeanyPlugin *, gpointer pdata, GDestroyNotify
free_func);
geany_plugin_set_data() can be called before the plugin's init, or
within, or any later. It'll set the data that is passed to all the hooks
(NULL is passed if geany_plugin_set_data() was never called). The
GDestroyNotify is called before the plugin is unloaded. Most importantly
it is also called if geany_plugin_set_data() was called before init()
and the plugin did not became activated at all.
I have successfully prototyped that the below Vala example can work
without leaks using the separate API function:
- p.register(Geany.API_VERSION, 224, Geany.ABI_VERSION,
- ref hooks, new Tester() /* LEAK */);
+ p.register(Geany.API_VERSION, 224, Geany.ABI_VERSION, ref hooks);
+ p.set_data(new Tester() /* no leak, g_object_unref is automatically
passed as destroy notify */);
Is that sound?
Best regards
Appendix: The prototype is like this:
using Geany;
class Tester
{
public void init(Plugin p) { }
public void help(Plugin p) { /* shows a dialog */ }
public void cleanup(Plugin p) { }
}
private PluginHooks hooks;
public bool geany_load_module(Plugin p, GLib.Module mod, int
geany_api_ver)
{
hooks.init = Tester.init;
hooks.help = Tester.help;
hooks.cleanup = Tester.cleanup;
p.register(Geany.API_VERSION, 224, Geany.ABI_VERSION,
ref hooks, new Tester() /* LEAK */);
mod.make_resident();
/* ... */
return true;
}
_______________________________________________
Devel mailing list
Devel@lists.geany.org
https://lists.geany.org/cgi-bin/mailman/listinfo/devel
_______________________________________________
Devel mailing list
Devel@lists.geany.org
https://lists.geany.org/cgi-bin/mailman/listinfo/devel