From de44b83fcd94a8af4414d69313844af8fd9f6b0d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sun, 14 Sep 2008 19:10:44 +0200 Subject: [PATCH] New interface header Provides structures used for managing interfaces, macros for declaring and defining interfaces. Convinience macros to bundle buildin and plugin interfaces. --- src/lib/interface.h | 204 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 src/lib/interface.h diff --git a/src/lib/interface.h b/src/lib/interface.h new file mode 100644 index 000000000..bc114f7e7 --- /dev/null +++ b/src/lib/interface.h @@ -0,0 +1,204 @@ +/* + interface.h - Lumiera interface macros and structures + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_INTERFACE_H +#define LUMIERA_INTERFACE_H + +#include "lib/luid.h" +#include "lib/ppmpl.h" + +/* + Interface declaration macros + */ + +#define LUMIERA_INTERFACE_INAME(name, version) lumiera_interface_##name##_##version +#define LUMIERA_INTERFACE_DNAME(iname, dname, version) dname##_##version##_interface + +#define LUMIERA_INTERFACE_TYPE(name, version) struct LUMIERA_INTERFACE_INAME(name, version) +#define LUMIERA_INTERFACE_CAST(name, version) (LUMIERA_INTERFACE_TYPE(name, version)*) + + + +#define PPMPL_FOREACH_LUMIERA_INTERFACE_SLOT(ret, name, params) ret (*name) params; lumiera_uid name##_uid; + + +#define LUMIERA_INTERFACE_DECLARE(name, version, ...) \ +LUMIERA_INTERFACE_TYPE(name, version) \ +{ \ + lumiera_interface interface_header_; \ + PPMPL_FOREACH(_, __VA_ARGS__) \ +} + + +/* + Interface definition macros + */ + + +#ifdef __cplusplus +#define PPMPL_FOREACH_LUMIERA_INTERFACE_MAP(slot, function, uid) \ + function, LUMIERA_UID_INITIALIZER (uid), +#else +#define PPMPL_FOREACH_LUMIERA_INTERFACE_MAP(slot, function, uid) \ + .slot = function, .slot##_uid = LUMIERA_UID_INITIALIZER (uid), +#endif + + +/** + * + * + * + * + * + * + * + * + * + * + */ +#define LUMIERA_INTERFACE_INITIALIZER(iname, version, name, descriptor, data, acquire, release, ...) \ +{ \ + { \ + #name, \ + version, \ + sizeof (LUMIERA_INTERFACE_TYPE(iname, version)), \ + descriptor, \ + data, \ + acquire, \ + release \ + }, \ + PPMPL_FOREACH(_, __VA_ARGS__) \ +} + + +#define LUMIERA_INTERFACE_DEFINE(iname, version, name, descriptor, data, acquire, release, ...) \ +LUMIERA_INTERFACE_TYPE(iname, version) LUMIERA_INTERFACE_DNAME(iname, name, version) = \ + LUMIERA_INTERFACE_INITIALIZER(iname, version, name, descriptor, data, acquire, release, __VA_ARGS__); + + + +#define PPMPL_FOREACH_L1_P1_LUMIERA_INTERFACE(iname, version, name, descriptor, data, acquire, release, ...) \ +LUMIERA_INTERFACE_DEFINE (iname, version, \ + name, \ + descriptor, \ + data, \ + acquire, \ + release, \ + __VA_ARGS__ \ + ); + + +#define PPMPL_FOREACH_L1_P2_LUMIERA_INTERFACE(iname, version, name, descriptor, data, acquire, release, ...) \ + &LUMIERA_INTERFACE_DNAME(iname, name, version).interface_header_, + + +#define LUMIERA_PLUGIN(descriptor, data, acquire, release, luid, ...) \ +PPMPL_FOREACH_L1(_P1_, __VA_ARGS__) \ +static const LumieraInterface* \ +plugin_interfaces (void) \ +{ \ + static const LumieraInterface interfaces[] = \ + { \ + PPMPL_FOREACH_L1(_P2_, __VA_ARGS__) \ + NULL \ + }; \ + return interfaces; \ +} \ +LUMIERA_INTERFACE_DEFINE (plugin, 0, \ + lumiera_plugin, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + LUMIERA_INTERFACE_MAP (plugin_interfaces, plugin_interfaces, luid) \ + ) + + + +#define LUMIERA_EXPORT(queryfunc, ...) \ +PPMPL_FOREACH_L1(_P1_, __VA_ARGS__) \ +static const LumieraInterface* \ +queryfunc (void) \ +{ \ + static const LumieraInterface interfaces[] = \ + { \ + PPMPL_FOREACH_L1(_P2_, __VA_ARGS__) \ + NULL \ + }; \ + return interfaces; \ +} \ + + +typedef struct lumiera_interfaceslot_struct lumiera_interfaceslot; +typedef lumiera_interfaceslot* LumieraInterfaceslot; + +typedef struct lumiera_interface_struct lumiera_interface; +typedef lumiera_interface* LumieraInterface; + +/** + * This is just a placeholder for an entry in a interface table. + * It consists of one here generic, later correctly prototyped functionppointer and + * a unique identifier which is associated with this function. + */ +struct lumiera_interfaceslot_struct +{ + void (*func)(void); + lumiera_uid uid; +}; + + +/** + * Header for an interface, just the absolute necessary metadata. + */ +struct lumiera_interface_struct +{ + /** name of the interface */ + const char* name; + /** major version, 0 means experimental */ + unsigned version; + /** size of the whole interface structure (minor version) */ + size_t size; + + /** metadata descriptor, itself a interface (or NULL) */ + LumieraInterface descriptor; + + /** generic data to be used by the implementation */ + void* data; + + /** must be called before this interface is used, might be nested */ + LumieraInterface (*acquire)(LumieraInterface self); + /** called when finished with this interface, must match the acquire calls */ + void (*release)(LumieraInterface self); + + /** placeholder array for the following function slots, C++ doesn't support flexibe arrays */ +#ifndef __cplusplus + lumiera_interfaceslot functions[]; +#endif +}; + + +#endif /* LUMIERA_INTERFACE_H */ +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/