The RfC documents were written to complement discussions of the Lumiera developers; yet since the time where ''Ichthyo'' is working basically alone on the project, this kind of discussions have ceased. During the following years, some ideas promoted by the existing RfC documents became rather detached from the actual state of development in the code base. Many of the existing RfC documents require some commentary to place them into context, and some of the decisions taken in the early stage of the project should be **re-assessed**. This includes the decision to reject some proposals, which initially might have seemed desirable, yet could not be reconciled with the understanding of the matter and topic in question, as was gained through the ongoing analysis and development.
208 lines
6 KiB
Text
208 lines
6 KiB
Text
Design Process : All Plugin Interfaces Are C
|
|
============================================
|
|
|
|
[options="autowidth"]
|
|
|====================================
|
|
|*State* | _Dropped_
|
|
|*Date* | _2007-06-29_
|
|
|*Proposed by* | ct
|
|
|====================================
|
|
|
|
|
|
|
|
|
|
C interfaces
|
|
------------
|
|
When we offer interfaces for plugging in external code, we export them as C
|
|
interfaces.
|
|
|
|
|
|
|
|
|
|
Description
|
|
~~~~~~~~~~~
|
|
Lumiera will be based on a plugin architecture, the core is just a skeleton
|
|
with very few components. Everything else is loaded at runtime as _plugin_. C++
|
|
interfaces are hard to use by other programming languages. Thus I propose to
|
|
export every interface between these plugins as C interface which can much more
|
|
easily integrated in other languages.
|
|
|
|
.Further notes:
|
|
* dynamic loading of plugins, maybe unloading
|
|
* proper interface versioning
|
|
|
|
|
|
Implementation Proposal
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
* keep the interface in a C struct (POD).
|
|
* the interface is versioned
|
|
* first member is a _size_ which will be initialized by the actual
|
|
implementation
|
|
* followed by function pointers defining the interface, see:
|
|
link:{rfc}/CCodingStyleGuide.html[C-coding style guide]
|
|
|
|
* everything added is considered immutable for this interface version
|
|
* new functions are added to the end (thus changing size)
|
|
* function pointers must be implemented, never be NULL
|
|
|
|
* a given interface version can be extended (but nothing removed)
|
|
* code using an interface just needs to check once if the size he get from a
|
|
supplier is >= what it expects, then the interface suffices its
|
|
requirements
|
|
* functions are versioned too, old version might be superseded by newer ones,
|
|
but the interface still needs to provide backward compatibility functions
|
|
* when old function are really deprecated, the interface version is bumped
|
|
and the old functions are removed from the struct
|
|
|
|
|
|
Example define the interface structure:
|
|
|
|
[source,C]
|
|
----
|
|
struct lumiera_plugin_audio_interface_1
|
|
{
|
|
size_t size;
|
|
|
|
// Now the prototypes for the interface
|
|
AudioSample (*sample_normalize_limit_1)(AudioSample self, int limit);
|
|
unsigned (*sample_rate_1) (AudioSample self);
|
|
AudioSample (*sample_set_rate_1) (AudioSample self, unsigned rate);
|
|
|
|
// a later version might take a double as limit
|
|
AudioSample (*sample_normalize_limit_2)(AudioSample self, double limit);
|
|
}
|
|
----
|
|
|
|
|
|
Example how a plugin 'thiseffect' initializes the struct:
|
|
|
|
[source,C]
|
|
----
|
|
struct lumiera_plugin_audio_interface_1
|
|
lumiera_plugin_audio_thiseffect_interface =
|
|
{
|
|
// maybe we want to initialize size somewhat smarter
|
|
sizeof(struct lumiera_plugin_audio_interface_1),
|
|
|
|
// this are the actual functions implemented in 'thiseffect'
|
|
lumiera_plugin_audio_thiseffect_sample_normalize_limit_1,
|
|
lumiera_plugin_audio_thiseffect_sample_rate_1,
|
|
lumiera_plugin_audio_thiseffect_sample_set_rate_1,
|
|
lumiera_plugin_audio_thiseffect_sample_normalize_limit_2
|
|
}
|
|
----
|
|
|
|
|
|
Example how it will be used (schematic code):
|
|
|
|
[source,C]
|
|
----
|
|
int main()
|
|
{
|
|
// get the function vector
|
|
void* thiseffecthandle = dlopen("thiseffect.so");
|
|
struct lumiera_plugin_audio_interface_1* thiseffect =
|
|
dlsym(thiseffecthandle, "lumiera_plugin_audio_thiseffect_interface");
|
|
|
|
// call a function
|
|
thiseffect.sample_normalize_limit_1 (somesample, 1);
|
|
}
|
|
----
|
|
|
|
|
|
Further notes:
|
|
|
|
That above gives only a idea, the datastructure needs to be extended with some
|
|
more information (reference counter?). The first few functions should be common
|
|
for all interfaces (init, destroy, ...). Opening and initialization will be
|
|
handled more high level than in the example above. Some macros which make
|
|
versioning simpler and so on.
|
|
|
|
|
|
|
|
|
|
Tasks
|
|
^^^^^
|
|
* Write some support macros when we know how to do it
|
|
|
|
|
|
Pros
|
|
^^^^
|
|
* Easier usage/extension from other languages.
|
|
|
|
|
|
Cons
|
|
^^^^
|
|
* Adds some constraints on possible interfaces, the glue code has to be
|
|
maintained.
|
|
|
|
|
|
Alternatives
|
|
^^^^^^^^^^^^
|
|
* Just only use C++
|
|
* Maybe SWIG?
|
|
* Implement lumiera in C instead C++
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
~~~~~~~~~
|
|
Not sure yet, maybe someone has a better idea.
|
|
|
|
|
|
|
|
|
|
Comments
|
|
--------
|
|
After a talk on IRC ichthyo and me agreed on making lumiera a multi language
|
|
project where each part can be written in the language which will fit it best.
|
|
Language purists might disagree on such a mix, but I believe the benefits
|
|
outweigh the drawbacks.
|
|
|
|
ct:: '2007-07-03 05:51:06'
|
|
|
|
C is the only viable choice here. Perhaps some sort of ``test bench'' could be
|
|
designed to rigorously test plugins for any problems which may cause Lumiera to
|
|
become unstable (memory leaks etc).
|
|
|
|
Deltafire:: '2007-07-03 12:17:09'
|
|
|
|
after a talk on irc, we decided to do it this way, further work will be
|
|
documented in the repository (tiddlywiki/source)
|
|
|
|
ct:: '2007-07-11 13:10:07'
|
|
|
|
.State -> Dropped
|
|
Development took another direction over the course of the years;
|
|
Lumiera is _not_ based on a _generic plug-in Architecture_ and the topic
|
|
of interfaces for _dedicated plugins_ still needs to be worked out
|
|
|
|
Ichthyostega:: '2023-10-24 22:55:23'
|
|
|
|
|
|
|
|
Conclusion
|
|
----------
|
|
Initially there was agreement over the general direction set out by this proposal.
|
|
However, _Ichthyo_ was always skeptical regarding the benefits of a generic plug-in
|
|
Architecture. Experience with high-profile projects based on such a concept seem
|
|
to show both tremendous possibilities, especially regarding user involvement, but
|
|
at the same time also indicate serious problems with long-term sustainability.
|
|
|
|
The practical development -- after some point mostly driven ahead by _Ichthyo_ -- never
|
|
really embraced that idea; rather structuring by internal interfaces and contracts was
|
|
preferred. The basic system for loading of Plug-ins, as indicated by this proposal,
|
|
is still used though to load some dedicated plug-ins, most notably the GUI.
|
|
|
|
To draw a conclusion: this proposal is now considered as *rejected*.
|
|
Instead, Ticket https://issues.lumiera.org/ticket/1212[#1212 »Extension Concept«]
|
|
was added to the list of relevant
|
|
https://issues.lumiera.org/report/17[»Focus Topics«] for further development.
|
|
|
|
.........
|
|
|
|
.........
|
|
|
|
''''
|
|
Back to link:/x/DesignProcess.html[Lumiera Design Process overview]
|