[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/phonon
From: Matthias Kretz <kretz () kde ! org>
Date: 2008-02-29 23:39:58
Message-ID: 1204328398.590625.20420.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 780776 by mkretz:
add dox for internal Iface class
M +85 -0 phonondefs_p.h
--- trunk/KDE/kdelibs/phonon/phonondefs_p.h #780775:780776
@@ -176,6 +176,91 @@
} // anonymous namespace
+ /**
+ * \internal
+ *
+ * \brief Helper class to cast the backend object to the correct version of the interface.
+ *
+ * Additions to the backend interfaces cannot be done by adding virtual methods as that would
+ * break the binary interface. So the old class is renamed and a new class with the old name
+ * inheriting the old class is added, containing all the new virtual methods.
+ * Example:
+ * \code
+ class FooInterface
+ {
+ public:
+ virtual ~FooInterface() {}
+ virtual oldMethod() = 0;
+ };
+ Q_DECLARE_INTERFACE(FooInterface, "FooInterface0.phonon.kde.org")
+ * \endcode
+ * becomes
+ * \code
+ class FooInterface0
+ {
+ public:
+ virtual ~FooInterface0() {}
+ virtual oldMethod() = 0;
+ };
+ class FooInterface : public FooInterface0
+ {
+ public:
+ virtual newMethod() = 0;
+ };
+ Q_DECLARE_INTERFACE(FooInterface0, "FooInterface0.phonon.kde.org")
+ Q_DECLARE_INTERFACE(FooInterface, "FooInterface1.phonon.kde.org")
+ * \endcode
+ *
+ * With this, backends compiled against the old header can be qobject_casted to FooInterface0,
+ * but not to FooInterface. On the other hand backends compiled against the new header (they first
+ * need to implement newMethod) can only be qobject_casted to FooInterface but not to
+ * FooInterface0. (The qobject_cast relies on the string in Q_DECLARE_INTERFACE and not the
+ * class name which is why it behaves that way.)
+ *
+ * Now, in order to call oldMethod, the code needs to try to cast to both FooInterface and
+ * FooInterface0 (new backends will work with the former, old backends with the latter) and then
+ * if one of them in non-zero call oldMethod on it.
+ *
+ * To call newMethod only a cast to FooInterface needs to be done.
+ *
+ * The Iface class does all this for you for up to three (for now) interface revisions. Just
+ * create an object like this:
+ * \code
+ Iface<FooInterface, FooInterface0> iface0(d);
+ if (iface0) {
+ iface0->oldMethod();
+ }
+ Iface<FooInterface> iface(d);
+ if (iface) {
+ iface->newMethod();
+ }
+ * \endcode
+ *
+ * This becomes a bit more convenient if you add macros like this:
+ * \code
+ #define IFACES1 FooInterface
+ #define IFACES0 IFACES1, FooInterface0
+ * \endcode
+ * which you can use like this:
+ * \code
+ Iface<IFACES0> iface0(d);
+ if (iface0) {
+ iface0->oldMethod();
+ }
+ Iface<IFACES1> iface(d);
+ if (iface) {
+ iface->newMethod();
+ }
+ * \endcode
+ * With the next revision you can then change the macros to
+ * \code
+ #define IFACES2 FooInterface
+ #define IFACES1 IFACES2, FooInterface1
+ #define IFACES0 IFACES1, FooInterface0
+ * \endcode
+ *
+ * \author Matthias Kretz <kretz@kde.org>
+ */
template<class T0, class T1 = NoIface, class T2 = NoIface>
class Iface
{
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic