[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