Commit cdb878bc authored by Jim Nelson's avatar Jim Nelson

Changed SPIT to pass Spit.EntryPointParams struct rather than plain values to...

Changed SPIT to pass Spit.EntryPointParams struct rather than plain values to allow for future expansion.  This was precipitated by the publishing plugins needed to know their module file early so they can load their icons.  Also updated the simple-plugin, which suffered from bitrot after some earlier interface changes.
parent 54e44f78
......@@ -31,14 +31,12 @@ private class ShotwellPublishingExtraServices : Object, Spit.Module {
}
// This entry point is required for all SPIT modules.
public Spit.Module? spit_entry_point(int host_min_spit_interface, int host_max_spit_interface,
out int module_spit_interface) {
module_spit_interface = Spit.negotiate_interfaces(host_min_spit_interface, host_max_spit_interface,
Spit.CURRENT_INTERFACE);
if (module_spit_interface == Spit.UNSUPPORTED_INTERFACE)
return null;
public Spit.Module? spit_entry_point(Spit.EntryPointParams *params) {
params->module_spit_interface = Spit.negotiate_interfaces(params->host_min_spit_interface,
params->host_max_spit_interface, Spit.CURRENT_INTERFACE);
return new ShotwellPublishingExtraServices();
return (params->module_spit_interface != Spit.UNSUPPORTED_INTERFACE)
? new ShotwellPublishingExtraServices() : null;
}
// valac wants a default entry point, so valac gets a default entry point
......
......@@ -35,14 +35,12 @@ private class ShotwellPublishingCoreServices : Object, Spit.Module {
}
// This entry point is required for all SPIT modules.
public Spit.Module? spit_entry_point(int host_min_spit_interface, int host_max_spit_interface,
out int module_spit_interface) {
module_spit_interface = Spit.negotiate_interfaces(host_min_spit_interface, host_max_spit_interface,
Spit.CURRENT_INTERFACE);
if (module_spit_interface == Spit.UNSUPPORTED_INTERFACE)
return null;
public Spit.Module? spit_entry_point(Spit.EntryPointParams *params) {
params->module_spit_interface = Spit.negotiate_interfaces(params->host_min_spit_interface,
params->host_max_spit_interface, Spit.CURRENT_INTERFACE);
return new ShotwellPublishingCoreServices();
return (params->module_spit_interface != Spit.UNSUPPORTED_INTERFACE)
? new ShotwellPublishingCoreServices() : null;
}
// valac wants a default entry point, so valac gets a default entry point
......
......@@ -33,14 +33,12 @@ private class ShotwellTransitions : Object, Spit.Module {
}
// This entry point is required for all SPIT modules.
public Spit.Module? spit_entry_point(int host_min_spit_interface, int host_max_spit_interface,
out int module_spit_interface) {
module_spit_interface = Spit.negotiate_interfaces(host_min_spit_interface, host_max_spit_interface,
Spit.CURRENT_INTERFACE);
if (module_spit_interface == Spit.UNSUPPORTED_INTERFACE)
return null;
public Spit.Module? spit_entry_point(Spit.EntryPointParams *params) {
params->module_spit_interface = Spit.negotiate_interfaces(params->host_min_spit_interface,
params->host_max_spit_interface, Spit.CURRENT_INTERFACE);
return new ShotwellTransitions();
return (params->module_spit_interface != Spit.UNSUPPORTED_INTERFACE)
? new ShotwellTransitions() : null;
}
// This is here to keep valac happy.
......
......@@ -12,58 +12,35 @@ extern const string _VERSION;
//
private class SimplePluginModule : Object, Spit.Module {
public string get_name() {
public unowned string get_module_name() {
return "Simple Plugin Sample";
}
public string get_version() {
public unowned string get_version() {
return _VERSION;
}
// Every module needs to have a unique ID.
public string get_id() {
public unowned string get_id() {
return "org.yorba.shotwell.samples.simple-plugin";
}
public Spit.Pluggable[]? get_pluggables() {
public unowned Spit.Pluggable[]? get_pluggables() {
return null;
}
}
//
// The module is responsible for holding a ref to its Spit.Module until it's unloaded
// (see g_module_unload)
//
private SimplePluginModule? simple = null;
//
// spit_entry_point() is required for all SPIT modules.
//
public unowned Spit.Module? spit_entry_point(int host_min_spit_interface, int host_max_spit_interface,
out int module_spit_interface) {
public Spit.Module? spit_entry_point(Spit.EntryPointParams *params) {
// Spit.negotiate_interfaces is a simple way to deal with the parameters from the host
module_spit_interface = Spit.negotiate_interfaces(host_min_spit_interface, host_max_spit_interface,
Spit.CURRENT_INTERFACE);
if (module_spit_interface == Spit.UNSUPPORTED_INTERFACE)
return null;
// Although the entry point should only be called once, easy to guard against the possibility
// and still do the right thing
if (simple == null)
simple = new SimplePluginModule();
params->module_spit_interface = Spit.negotiate_interfaces(params->host_min_spit_interface,
params->host_max_spit_interface, Spit.CURRENT_INTERFACE);
return simple;
}
//
// The module is responsible for releasing its reference to its Spit.Module when the .so is
// unloaded from memory.
//
public void g_module_unload() {
simple = null;
return (params->module_spit_interface != Spit.UNSUPPORTED_INTERFACE)
? new SimplePluginModule() : null;
}
// This is here to keep valac happy.
......
......@@ -366,23 +366,29 @@ private void load_module(File file) {
Spit.EntryPoint spit_entry_point = (Spit.EntryPoint) entry;
assert(MIN_SPIT_INTERFACE <= Spit.CURRENT_INTERFACE && Spit.CURRENT_INTERFACE <= MAX_SPIT_INTERFACE);
module_rep.spit_interface = Spit.UNSUPPORTED_INTERFACE;
module_rep.spit_module = spit_entry_point(MIN_SPIT_INTERFACE, MAX_SPIT_INTERFACE,
out module_rep.spit_interface);
if (module_rep.spit_interface == Spit.UNSUPPORTED_INTERFACE) {
Spit.EntryPointParams params = Spit.EntryPointParams();
params.host_min_spit_interface = MIN_SPIT_INTERFACE;
params.host_max_spit_interface = MAX_SPIT_INTERFACE;
params.module_spit_interface = Spit.UNSUPPORTED_INTERFACE;
params.module_file = file;
module_rep.spit_module = spit_entry_point(&params);
if (params.module_spit_interface == Spit.UNSUPPORTED_INTERFACE) {
critical("Unable to load module %s: module reports no support for SPIT interfaces %d to %d",
file.get_path(), MIN_SPIT_INTERFACE, MAX_SPIT_INTERFACE);
return;
}
if (module_rep.spit_interface < MIN_SPIT_INTERFACE || module_rep.spit_interface > MAX_SPIT_INTERFACE) {
if (params.module_spit_interface < MIN_SPIT_INTERFACE || params.module_spit_interface > MAX_SPIT_INTERFACE) {
critical("Unable to load module %s: module reports unsupported SPIT version %d (out of range %d to %d)",
file.get_path(), module_rep.spit_interface, MIN_SPIT_INTERFACE, MAX_SPIT_INTERFACE);
return;
}
module_rep.spit_interface = params.module_spit_interface;
// verify type (as best as possible; still potential to segfault inside GType here)
if (!(module_rep.spit_module is Spit.Module))
module_rep.spit_module = null;
......
......@@ -48,26 +48,51 @@ public int negotiate_interfaces(int min_host_interface, int max_host_interface,
? UNSUPPORTED_INTERFACE : plugin_interface;
}
/**
* SPIT entry point parameters.
*
* The host application passes a pointer to this structure for the module's information.
* The pointer should //not// be held, as it may be freed or reused by the host application
* after calling the entry point. The module should copy any information it may need (or hold
* a GObject reference) in its own memory space.
*
* Note that the module //must// fill in the module_spit_interface field with the SPIT interface
* version it understands prior to returning control.
*/
public struct EntryPointParams {
/**
* The host's minimum supported interface version.
*/
public int host_min_spit_interface;
/**
* The host's maximum supported interface version.
*/
public int host_max_spit_interface;
/**
* The module returns here the interface version of SPIT it supports,
* {@link UNSUPPORTED_INTERFACE} otherwise.
*/
public int module_spit_interface;
/**
* A File object representing the library file (.so/la.) that the plugin was loaded from.
*/
public File module_file;
}
/**
* SPIT API entry point.
*
* Host application passes in the minimum and maximum version of the SPIT
* interface it supports (values are inclusive). The module returns the version it wishes to
* use and a pointer to a {@link Spit.Module} (which will remain ref'ed as long as the module is
* loaded in memory). The module should return {@link UNSUPPORTED_INTERFACE} is the min/max
* are out of its range and null for its Spit.Module. ({@link negotiate_interfaces} is good for
* dealing with this.)
* interface it supports (values are inclusive) in the {@link EntryPointParams} struct.
* The module returns the version it wishes to use and a pointer to a {@link Spit.Module} (which
* will remain ref'ed by the host as long as the module is loaded in memory). The module should
* return {@link UNSUPPORTED_INTERFACE} if the min/max are out of its range and null for its
* Spit.Module. ({@link negotiate_interfaces} is good for dealing with this.)
*
* @param host_min_spit_interface The host's minimum supported interface version.
* @param host_max_spit_interface The host's maximum supported interface version.
* @param module_spit_interface The interface version of SPIT the module supports,
* {@link UNSUPPORTED_INTERFACE} otherwise.
*
* @return A {@link Spit.Module} if the interface negotiation is acceptable, null otherwise.
*/
[CCode (has_target = false)]
public delegate Module? EntryPoint(int host_min_spit_interface, int host_max_spit_interface,
out int module_spit_interface);
public delegate Module? EntryPoint(EntryPointParams *params);
/**
* SPIT entry point name, which matches {@link EntryPoint}'s interface
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment