libqutim  0.3.2.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 <QPointer>
00031 #include <QSharedDataPointer>
00032 
00033 namespace qutim_sdk_0_3
00034 {
00035 class ObjectGeneratorPrivate;
00036 class ExtensionInfo;
00037 
00038 class ObjectGenerator;
00039 class ActionGenerator;
00040 typedef QList<const ObjectGenerator *> GeneratorList;
00041 
00042 class LIBQUTIM_EXPORT ObjectGeneratorHolderData : public QSharedData
00043 {
00044     Q_DISABLE_COPY(ObjectGeneratorHolderData)
00045 public:
00046     ObjectGenerator *generator() const;
00047     ActionGenerator *actionGenerator() const;
00048 
00049 private:
00050     friend class ObjectGenerator;
00051     ObjectGeneratorHolderData(ObjectGenerator *generator);
00052     ObjectGenerator *m_generator;
00053 };
00054 
00070 class LIBQUTIM_EXPORT ObjectGenerator
00071 {
00072     Q_DECLARE_PRIVATE(ObjectGenerator)
00073     Q_DISABLE_COPY(ObjectGenerator)
00074     Q_GADGET
00075 protected:
00079     ObjectGenerator();
00080 #ifndef Q_QDOC
00081     ObjectGenerator(ObjectGeneratorPrivate &priv);
00082 #endif
00083 public:
00084     typedef QExplicitlySharedDataPointer<ObjectGeneratorHolderData> Ptr;
00085 
00089     virtual ~ObjectGenerator();
00102     ObjectGenerator *addProperty(const QByteArray &name, const QVariant &value);
00106     inline QObject *generate() const
00107     { return generateHelper2(); }
00117     template<typename T>
00118     inline T *generate() const
00119     {
00120         QObject *object = generateHelper2();
00121         T *t = qobject_cast<T *>(object);
00122         if (!t) delete object;
00123         return t ? t : 0;
00124     }
00125 //      /**
00126 //      * @brief Generate object
00127 //      *
00128 //      * @param super Meta info of superiour class
00129 //      * @return Generated object or null if object doesn't extends class
00130 //      * represented by superiour meta info error
00131 //      */
00132 //      inline QObject *generate(const QMetaObject *super) const
00133 //      { return extends(super) ? generateHelper2() : 0; }
00134 //      /**
00135 //      * @brief Generate object
00136 //      *
00137 //      * @param id Identification of needed interface
00138 //      * @return Generated object or null if class doesn't implement interface
00139 //      */
00140 //      inline QObject *generate(const char *id) const
00141 //      { return extends(id) ? generateHelper2() : 0; }
00148     virtual const QMetaObject *metaObject() const = 0;
00155     bool hasInterface(const char *id) const;
00156 
00157     virtual QList<QByteArray> interfaces() const;
00158 
00159     // TODO: There should be a way for getting interfaces list
00160 //      virtual QList<const char *> interfaces() const = 0;
00167     bool extends(const QMetaObject *super) const;
00174     inline bool extends(const char *id) const
00175     { return id && hasInterface(id); }
00181     template<typename T>
00182     inline bool extends() const
00183     { return extends_helper<T>(reinterpret_cast<T *>(0)); }
00184 
00188     static bool isInited();
00192     static GeneratorList module(const QMetaObject *module);
00193 
00194     Ptr pointerHolder();
00198     static GeneratorList module(const char *iid);
00199     template<typename T> static inline GeneratorList module()
00200     { return module_helper<T>(reinterpret_cast<T *>(0)); }
00201 #ifndef Q_QDOC
00202     ExtensionInfo info() const;
00203 protected:
00204     template<typename T> static inline GeneratorList module_helper(const QObject *)
00205     { return ObjectGenerator::module(&T::staticMetaObject); }
00206     template<typename T> static inline GeneratorList module_helper(const void *)
00207     { return ObjectGenerator::module(qobject_interface_iid<T *>()); }
00208     template<typename T>
00209     inline bool extends_helper(const QObject *) const
00210     { return extends(&T::staticMetaObject); }
00211     template<typename T>
00212     inline bool extends_helper(const void *) const
00213     { return extends(qobject_interface_iid<T *>()); }
00214     QObject *generateHelper2() const;
00215 #endif
00216 protected:
00224     virtual QObject *generateHelper() const = 0;
00225     virtual void virtual_hook(int id, void *data);
00226     QScopedPointer<ObjectGeneratorPrivate> d_ptr;
00227 #ifndef Q_QDOC
00228 public:
00229     typedef ObjectGeneratorPrivate Data;
00230     inline Data *data() { return d_ptr.data(); }
00231 #endif
00232 };
00233 
00234 template<typename T, typename I0 = void,
00235 typename I1 = void, typename I2 = void, typename I3 = void,
00236 typename I4 = void, typename I5 = void, typename I6 = void,
00237 typename I7 = void, typename I8 = void, typename I9 = void>
00238 class GeneralGenerator : public ObjectGenerator
00239 {
00240     Q_DISABLE_COPY(GeneralGenerator)
00241 public:
00245     inline GeneralGenerator() {}
00246 protected:
00251     virtual QObject *generateHelper() const
00252     {
00253         return new T();
00254     }
00260     virtual const QMetaObject *metaObject() const
00261     {
00262         return &T::staticMetaObject;
00263     }
00270     virtual QList<QByteArray> interfaces() const
00271     {
00272         QList<QByteArray> result;
00273         addInterface<I0>(result);
00274         addInterface<I1>(result);
00275         addInterface<I2>(result);
00276         addInterface<I3>(result);
00277         addInterface<I4>(result);
00278         addInterface<I5>(result);
00279         addInterface<I6>(result);
00280         addInterface<I7>(result);
00281         addInterface<I8>(result);
00282         addInterface<I9>(result);
00283         return result;
00284     }
00285 private:
00286     template<typename Interface>
00287     Q_INLINE_TEMPLATE void addInterface(QList<QByteArray> &result, T *pointer = 0) const
00288     {
00289         Interface *i = pointer;
00290         Q_UNUSED(i);
00291         if (qobject_interface_iid<Interface*>())
00292             result << qobject_interface_iid<Interface*>();
00293     }
00294 };
00295 
00296 
00297 template<typename T, typename I0 = void,
00298 typename I1 = void, typename I2 = void, typename I3 = void,
00299 typename I4 = void, typename I5 = void, typename I6 = void,
00300 typename I7 = void, typename I8 = void, typename I9 = void>
00301 class SingletonGenerator : public GeneralGenerator<T, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9>
00302 {
00303     Q_DISABLE_COPY(SingletonGenerator)
00304 public:
00308     inline SingletonGenerator() {}
00309 protected:
00318     virtual QObject *generateHelper() const
00319     {
00320         if(m_object.isNull())
00321             m_object = new T;
00322         return m_object.data();
00323     }
00327     mutable QPointer<QObject> m_object;
00328 };
00329 }
00330 
00331 #endif // OBJECTGENERATOR_H
00332