diff --git a/wiki/support_library.html b/wiki/support_library.html index 44097d42b..95f735230 100644 --- a/wiki/support_library.html +++ b/wiki/support_library.html @@ -1691,16 +1691,18 @@ DAMAGE. <html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html> ***/ -
Interfaces are declared in headerfiles, they use some tool macros to give a convenient definition language.
+! Thoughts
+
+Interfaces are are immutable with the exception that new functions may be added. versioning should stay out of the view most of the time.
+
! Brainstorming
-This is just a sketch, using preprocessor metaprogramming.
-
-An interface need a name and a version, they form a block where the actual function prototypes can be added
+An interface need a name and a version, they form a block where the actual function prototypes can be added, new prototypes have to be added at the end, existing prototypes must never be changed.
{{{
-CINELERRA_INTERFACE(foo, 1,
+CINELERRA_INTERFACE(name, version,
...
);
}}}
@@ -1708,7 +1710,7 @@ CINELERRA_INTERFACE(foo, 1,
each function prototype must be given with its different parts, return type, name, arguments list, version
{{{
- CINELERRA_IPROTO(ret, name, (args), version),
+ CINELERRA_IPROTO(ret, name, (args)),
}}}
@@ -1716,27 +1718,45 @@ each function prototype must be given with its different parts, return type, nam
Together this would look like
{{{
CINELERRA_INTERFACE(foo, 1,
- CINELERRA_IPROTO(void, bar, (void), 1),
- CINELERRA_IPROTO(int, baz, (int i), 1)
+ CINELERRA_IPROTO(void, bar, (void)),
+ CINELERRA_IPROTO(int, baz, (int i))
+);
+
+CINELERRA_INTERFACE(foo, 2,
+ CINELERRA_IPROTO(void, bar, (void)),
+ CINELERRA_IPROTO(int, baz, (float i))
);
}}}
+Note that the version 2 interface changed the parameter from int to float for the 'baz' function.
+
which gets expanded to
{{{
struct cinelerra_interface_foo_1
{
struct cinelerra_interface interface_header_;
- void (*cinelerra_proto_foo_bar_1) (void);
- int (*cinelerra_proto_foo_baz_1) (int i);
+ void (*bar) (void);
+ int (*baz) (int i);
+};
+
+struct cinelerra_interface_foo_2
+{
+ struct cinelerra_interface interface_header_;
+ void (*bar) (void);
+ int (*baz) (float i);
};
}}}
A Plugin realizes an interface, this means actual functions are mapped to the correspondending slots in the interface structure.
{{{
-CINELERRA_IMPLEMENT_INTERFACE(interface, version, name, /* TODO some hooks here */
- CINELERRA_INTERFACE_FUNC(protoname, version, functionname),
+CINELERRA_INTERFACE_IMPLEMENT(interface, name,
+ CINELERRA_INTERFACE_VERSION(version,
+ /* TODO some hooks here */
+ CINELERRA_INTERFACE_FUNC(protoname, functionname),
+ ...
+ ),
...
);
}}}
@@ -1750,20 +1770,41 @@ my_bar_function (void)
}
int
-my_baz_function (int i)
+my_old_baz_function (int i)
{
...
}
-CINELERRA_IMPLEMENT_INTERFACE(foo, 1, myfoointerface, /* TODO some hooks here */
- CINELERRA_INTERFACE_FUNC(bar, 1, my_bar_function),
- CINELERRA_INTERFACE_FUNC(baz, 1, my_baz_function),
+int
+my_baz_function (float i)
+{
+ ...
+}
+
+CINELERRA_INTERFACE_IMPLEMENT(foo, myfoointerface,
+ CINELERRA_INTERFACE_VERSION(1,
+ /* TODO some hooks here */
+ CINELERRA_INTERFACE_FUNC(bar, my_bar_function),
+ CINELERRA_INTERFACE_FUNC(baz, my_old_baz_function)
+ ),
+ CINELERRA_INTERFACE_VERSION(2,
+ /* TODO some hooks here */
+ CINELERRA_INTERFACE_FUNC(bar, my_bar_function),
+ CINELERRA_INTERFACE_FUNC(baz, my_old_baz_function)
+ )
);
}}}
-which expands to something like:
+The interface implementations expands to something like:
{{{
-struct cinelerra_interface_foo_1 myfoointerface =
+struct cinelerra_interface_foo_1 myfoointerface_1 =
+{
+ /* TODO header initialization */
+ my_bar_function,
+ my_old_baz_function
+}
+
+struct cinelerra_interface_foo_2 myfoointerface_2 =
{
/* TODO header initialization */
my_bar_function,
@@ -1771,7 +1812,8 @@ struct cinelerra_interface_foo_1 myfoointerface =
}
}}}
-Note: the protoname and version args for CINELERRA_INTERFACE_FUNC will be used for placement initialization and type checking, not mentioned here. This would allow to initialize this structure out of order.
+Note: the protoname and version args for ~CINELERRA_INTERFACE_FUNC will be used for placement initialization and type checking, not mentioned here. This would allow to initialize this structure out of order.
+
! Compatibility matrix |>|>|!Source compatibility| |!~~CALLER~~\^^CALLEE^^ *|OLD^^**^^|NEW^^**^^| |OLD|works|works<<br>>but a recent interface definition must be available| -|NEW|update callee using new interface revision|works| +|NEW|callee has to be updated using new interface revision|works| |>|>|!Binary compatibility| |OLD|works|works| -|NEW|caller gets 'revision not sufficient' at runtime<<br>>and needs to implement fallbacks|works| +|NEW|caller gets 'revision not sufficient' at runtime<<br>>and should implement fallbacks|works| ^^*^^) CALLER is the user of an interface, CALLEE is the interface provider (usually a plugin) ^^**^^) OLD means a initial revision, NEW means some later revision of an interface