libqutim 0.3.1.0
objectgenerator.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** qutIM - instant messenger
00004 **
00005 ** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
00006 **
00007 *****************************************************************************
00008 **
00009 ** $QUTIM_BEGIN_LICENSE$
00010 ** This program is free software: you can redistribute it and/or modify
00011 ** it under the terms of the GNU General Public License as published by
00012 ** the Free Software Foundation, either version 3 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 ** See the GNU General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU General Public License
00021 ** along with this program.  If not, see http://www.gnu.org/licenses/.
00022 ** $QUTIM_END_LICENSE$
00023 **
00024 ****************************************************************************/
00025 
00026 #ifndef OBJECTGENERATOR_H
00027 #define OBJECTGENERATOR_H
00028 
00029 #include "libqutim_global.h"
00030 #include <QWeakPointer>
00031 
00032 namespace qutim_sdk_0_3
00033 {
00034 class ObjectGeneratorPrivate;
00035 class ExtensionInfo;
00036 
00037 class ObjectGenerator;
00038 class ActionGenerator;
00039 typedef QList<const ObjectGenerator *> GeneratorList;
00040 
00041 class LIBQUTIM_EXPORT ObjectGeneratorHolderData : public QSharedData
00042 {
00043     Q_DISABLE_COPY(ObjectGeneratorHolderData)
00044 public:
00045     ObjectGenerator *generator() const;
00046     ActionGenerator *actionGenerator() const;
00047 
00048 private:
00049     friend class ObjectGenerator;
00050     ObjectGeneratorHolderData(ObjectGenerator *generator);
00051     ObjectGenerator *m_generator;
00052 };
00053 
00069 class LIBQUTIM_EXPORT ObjectGenerator
00070 {
00071     Q_DECLARE_PRIVATE(ObjectGenerator)
00072     Q_DISABLE_COPY(ObjectGenerator)
00073     Q_GADGET
00074 protected:
00078     ObjectGenerator();
00079 #ifndef Q_QDOC
00080     ObjectGenerator(ObjectGeneratorPrivate &priv);
00081 #endif
00082 public:
00083     typedef QExplicitlySharedDataPointer<ObjectGeneratorHolderData> Ptr;
00084 
00088     virtual ~ObjectGenerator();
00101     ObjectGenerator *addProperty(const QByteArray &name, const QVariant &value);
00105     inline QObject *generate() const
00106     { return generateHelper2(); }
00116     template<typename T>
00117     inline T *generate() const
00118     {
00119         QObject *object = generateHelper2();
00120         T *t = qobject_cast<T *>(object);
00121         if (!t) delete object;
00122         return t ? t : 0;
00123     }
00124 //      /**
00125 //      * @brief Generate object
00126 //      *
00127 //      * @param super Meta info of superiour class
00128 //      * @return Generated object or null if object doesn't extends class
00129 //      * represented by superiour meta info error
00130 //      */
00131 //      inline QObject *generate(const QMetaObject *super) const
00132 //      { return extends(super) ? generateHelper2() : 0; }
00133 //      /**
00134 //      * @brief Generate object
00135 //      *
00136 //      * @param id Identification of needed interface
00137 //      * @return Generated object or null if class doesn't implement interface
00138 //      */
00139 //      inline QObject *generate(const char *id) const
00140 //      { return extends(id) ? generateHelper2() : 0; }
00147     virtual const QMetaObject *metaObject() const = 0;
00154     bool hasInterface(const char *id) const;
00155 
00156     virtual QList<QByteArray> interfaces() const;
00157 
00158     // TODO: There should be a way for getting interfaces list
00159 //      virtual QList<const char *> interfaces() const = 0;
00166     bool extends(const QMetaObject *super) const;
00173     inline bool extends(const char *id) const
00174     { return id && hasInterface(id); }
00180     template<typename T>
00181     inline bool extends() const
00182     { return extends_helper<T>(reinterpret_cast<T *>(0)); }
00183 
00187     static bool isInited();
00191     static GeneratorList module(const QMetaObject *module);
00192 
00193     Ptr pointerHolder();
00197     static GeneratorList module(const char *iid);
00198     template<typename T> static inline GeneratorList module()
00199     { return module_helper<T>(reinterpret_cast<T *>(0)); }
00200 #ifndef Q_QDOC
00201     ExtensionInfo info() const;
00202 protected:
00203     template<typename T> static inline GeneratorList module_helper(const QObject *)
00204     { return ObjectGenerator::module(&T::staticMetaObject); }
00205     template<typename T> static inline GeneratorList module_helper(const void *)
00206     { return ObjectGenerator::module(qobject_interface_iid<T *>()); }
00207     template<typename T>
00208     inline bool extends_helper(const QObject *) const
00209     { return extends(&T::staticMetaObject); }
00210     template<typename T>
00211     inline bool extends_helper(const void *) const
00212     { return extends(qobject_interface_iid<T *>()); }
00213     QObject *generateHelper2() const;
00214 #endif
00215 protected:
00223     virtual QObject *generateHelper() const = 0;
00224     virtual void virtual_hook(int id, void *data);
00225     QScopedPointer<ObjectGeneratorPrivate> d_ptr;
00226 #ifndef Q_QDOC
00227 public:
00228     typedef ObjectGeneratorPrivate Data;
00229     inline Data *data() { return d_ptr.data(); }
00230 #endif
00231 };
00232 
00233 template<typename T, typename I0 = void,
00234 typename I1 = void, typename I2 = void, typename I3 = void,
00235 typename I4 = void, typename I5 = void, typename I6 = void,
00236 typename I7 = void, typename I8 = void, typename I9 = void>
00237 class GeneralGenerator : public ObjectGenerator
00238 {
00239     Q_DISABLE_COPY(GeneralGenerator)
00240 public:
00244     inline GeneralGenerator() {}
00245 protected:
00250     virtual QObject *generateHelper() const
00251     {
00252         return new T();
00253     }
00259     virtual const QMetaObject *metaObject() const
00260     {
00261         return &T::staticMetaObject;
00262     }
00269     virtual QList<QByteArray> interfaces() const
00270     {
00271         QList<QByteArray> result;
00272         addInterface<I0>(result);
00273         addInterface<I1>(result);
00274         addInterface<I2>(result);
00275         addInterface<I3>(result);
00276         addInterface<I4>(result);
00277         addInterface<I5>(result);
00278         addInterface<I6>(result);
00279         addInterface<I7>(result);
00280         addInterface<I8>(result);
00281         addInterface<I9>(result);
00282         return result;
00283     }
00284 private:
00285     template<typename Interface>
00286     Q_INLINE_TEMPLATE void addInterface(QList<QByteArray> &result, T *pointer = 0) const
00287     {
00288         register Interface *i = pointer;
00289         Q_UNUSED(i);
00290         if (qobject_interface_iid<Interface*>())
00291             result << qobject_interface_iid<Interface*>();
00292     }
00293 };
00294 
00295 
00296 template<typename T, typename I0 = void,
00297 typename I1 = void, typename I2 = void, typename I3 = void,
00298 typename I4 = void, typename I5 = void, typename I6 = void,
00299 typename I7 = void, typename I8 = void, typename I9 = void>
00300 class SingletonGenerator : public GeneralGenerator<T, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9>
00301 {
00302     Q_DISABLE_COPY(SingletonGenerator)
00303 public:
00307     inline SingletonGenerator() {}
00308 protected:
00317     virtual QObject *generateHelper() const
00318     {
00319         if(m_object.isNull())
00320             m_object = new T;
00321         return m_object.data();
00322     }
00326     mutable QWeakPointer<QObject> m_object;
00327 };
00328 }
00329 
00330 #endif // OBJECTGENERATOR_H
00331