Passing an interface handle to plugins

Plugins which in turn want to open other interfaces need some way to
access the interfaces system itself. This is realized with a 'interface'
implementing the interface api and passed to the plugins initialization
routine.

A plugin which wishes to open other interfaces must
safe this in a local variable defined by LUMIERA_PLUGIN_INTERFACEHANDLE
with the LUMIERA_PLUGIN_STORE_INTERFACEHANDLE macro.

The LUMIERA_INTERFACE_OPEN and LUMIERA_INTERFACE_CLOSE macros change their
definition depending on compiled as buildin or plugin to account for that.
This commit is contained in:
Christian Thaeter 2008-11-07 03:58:57 +01:00
parent f5da688c48
commit 52a4f7743a
3 changed files with 106 additions and 19 deletions

View file

@ -37,6 +37,8 @@
* Interfaces can be opened multiple times and cross reference each other.
*/
/* the mother of all interfaces */
LumieraInterface lumiera_interface_interface;
static LumieraInterfacenode
lumiera_interface_open_interfacenode (LumieraInterfacenode self);
@ -201,7 +203,7 @@ lumiera_interface_open_interfacenode (LumieraInterfacenode self)
{
TRACE (interface, "Acquire %s", self->interface->name);
collect_dependencies = self->deps?0:1;
self->interface = self->interface->acquire (self->interface);
self->interface = self->interface->acquire (self->interface, lumiera_interface_interface);
}
}
else
@ -301,6 +303,41 @@ lumiera_interfacenode_close (LumieraInterfacenode self)
}
}
/**
* Definitinon of 'the mother of all interfaces'
* since this interface is singleton and required for any component to open any other
* interface this should get a very stable interface and likely never change.
*/
LUMIERA_EXPORT(
LUMIERA_INTERFACE_DEFINE (lumieraorg_interface, 0,
lumieraorg_interface,
NULL,
NULL,
NULL,
LUMIERA_INTERFACE_MAP (open, "\322\165\227\133\252\355\125\104\157\167\253\267\117\273\174\022",
lumiera_interface_open),
LUMIERA_INTERFACE_MAP (close, "\264\037\253\243\312\273\024\104\030\007\076\006\154\071\340\102",
lumiera_interface_close),
LUMIERA_INTERFACE_MAP (version, "\004\272\070\214\006\235\047\212\007\165\115\221\146\274\217\324",
lumiera_interface_version),
)
)
void
lumiera_interface_init (void)
{
LUMIERA_INTERFACE_REGISTEREXPORTED;
lumiera_interface_interface =
lumiera_interface_open ("lumieraorg_interface", 0, 0, "lumieraorg_interface");
}
void
lumiera_interface_destroy (void)
{
lumiera_interface_close (lumiera_interface_interface);
LUMIERA_INTERFACE_UNREGISTEREXPORTED;
}
/*
// Local Variables:

View file

@ -292,7 +292,10 @@ LUMIERA_PLUGININTERFACE
/**
* Create a plugin interface when being copiled as plugin
*/
#ifdef LUMIERA_PLUGIN
#ifdef LUMIERA_PLUGIN /* compile as plugin */
#define LUMIERA_PLUGIN_INTERFACEHANDLE static LUMIERA_INTERFACE_HANDLE(lumieraorg_interface, 0) lumiera_interface_handle
#define LUMIERA_PLUGIN_STORE_INTERFACEHANDLE(name) lumiera_interface_handle = LUMIERA_INTERFACE_CAST (lumieraorg_interface, 0) name
#define LUMIERA_PLUGININTERFACE \
LUMIERA_INTERFACE_INSTANCE (lumieraorg__plugin, 0, \
lumieraorg_plugin, \
@ -305,7 +308,19 @@ LUMIERA_INTERFACE_INSTANCE (lumieraorg__plugin, 0,
);
#define LUMIERA_INTERFACE_REGISTEREXPORTED
#define LUMIERA_INTERFACE_UNREGISTEREXPORTED
#else
#define LUMIERA_INTERFACE_OPEN(interface, version, minminor, name) \
LUMIERA_INTERFACE_CAST(interface, version) lumiera_interface_handle->open (#interface, version, minminor, #name)
#define LUMIERA_INTERFACE_CLOSE(handle) \
lumiera_interface_handle->close (&(handle)->interface_header_)
#else /* compile as buildin */
#define LUMIERA_PLUGIN_INTERFACEHANDLE static LUMIERA_INTERFACE_HANDLE(lumieraorg_interface, 0) lumiera_interface_handle
#define LUMIERA_PLUGIN_STORE_INTERFACEHANDLE(name) lumiera_interface_handle = LUMIERA_INTERFACE_CAST (lumieraorg_interface, 0) name
#define LUMIERA_PLUGININTERFACE
/**
* Register all exported interfaces when not a plugin
@ -319,9 +334,17 @@ LUMIERA_INTERFACE_INSTANCE (lumieraorg__plugin, 0,
*/
#define LUMIERA_INTERFACE_UNREGISTEREXPORTED \
lumiera_interfaceregistry_bulkremove_interfaces (lumiera_plugin_interfaces())
#define LUMIERA_INTERFACE_OPEN(interface, version, minminor, name) \
LUMIERA_INTERFACE_CAST(interface, version) lumiera_interface_open (#interface, version, minminor, #name)
#define LUMIERA_INTERFACE_CLOSE(handle) \
lumiera_interface_close (&(handle)->interface_header_)
#endif
/**
* create a handle for a interface (WIP)
*/
@ -329,12 +352,6 @@ LUMIERA_INTERFACE_INSTANCE (lumieraorg__plugin, 0,
#define LUMIERA_INTERFACE_HANDLE(interface, version) \
LUMIERA_INTERFACE_TYPE(interface, version)*
#define LUMIERA_INTERFACE_OPEN(interface, version, minminor, name) \
LUMIERA_INTERFACE_CAST(interface, version) lumiera_interface_open (#interface, version, minminor, #name)
#define LUMIERA_INTERFACE_CLOSE(handle) \
lumiera_interface_close (&(handle)->interface_header_)
typedef struct lumiera_interfaceslot_struct lumiera_interfaceslot;
typedef lumiera_interfaceslot* LumieraInterfaceslot;
@ -378,9 +395,12 @@ struct lumiera_interface_struct
* Must be called before this interface is used.
* might be nested.
* @param self pointer to the interface to be acquired
* @param interfaces pointer to a 'interfaces' interface giving plugins access to
* opening and closing interfaces, this is already opened and if a plugin
* wants to use other interfaces it has to store this pointer
* @return pointer to the interface or NULL on error
*/
LumieraInterface (*acquire)(LumieraInterface self);
LumieraInterface (*acquire)(LumieraInterface self, LumieraInterface interfaces);
/**
* called when finished using this interface
* must match the acquire calls
@ -394,15 +414,6 @@ struct lumiera_interface_struct
#endif
};
/**
* Plugin interface
*/
LUMIERA_INTERFACE_DECLARE (lumieraorg__plugin, 0,
LUMIERA_INTERFACE_SLOT (LumieraInterface*, plugin_interfaces, (void)),
);
/*
API to handle interfaces
*/
@ -436,6 +447,41 @@ lumiera_interface_close (LumieraInterface self);
unsigned
lumiera_interface_version (LumieraInterface self, const char* iname);
/**
* Define an interface for the above
*/
LUMIERA_INTERFACE_DECLARE (lumieraorg_interface, 0,
LUMIERA_INTERFACE_SLOT (LumieraInterface,
open,
(const char* interface, unsigned version, size_t minminorversion, const char* name)),
LUMIERA_INTERFACE_SLOT (void, close, (LumieraInterface self)),
LUMIERA_INTERFACE_SLOT (unsigned, version, (LumieraInterface self, const char* iname)),
);
/**
* registering implementations of the above interface
*/
void
lumiera_interface_init (void);
/**
* deregistering implementations of the above interface
*/
void
lumiera_interface_destroy (void);
/**
* Plugin interface
*/
LUMIERA_INTERFACE_DECLARE (lumieraorg__plugin, 0,
LUMIERA_INTERFACE_SLOT (LumieraInterface*, plugin_interfaces, (void)),
);
#endif /* LUMIERA_INTERFACE_H */
/*

View file

@ -110,6 +110,8 @@ lumiera_interfaceregistry_init (void)
LUMIERA_DIE (ERRNO);
lumiera_recmutex_init (&lumiera_interface_mutex, "interfaceregistry", &NOBUG_FLAG(interfaceregistry));
lumiera_interface_init ();
}
@ -118,6 +120,8 @@ lumiera_interfaceregistry_destroy (void)
{
TRACE (interfaceregistry);
lumiera_interface_destroy ();
if (lumiera_pluginregistry)
psplay_delete (lumiera_pluginregistry);
lumiera_pluginregistry = NULL;