Advertisement
Guest User

parallelworkers.h

a guest
Aug 14th, 2015
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.60 KB | None | 0 0
  1. #ifndef PARALLELWORKERS_H
  2. #define PARALLELWORKERS_H
  3.  
  4. // Qt includes
  5.  
  6. #include <QObject>
  7.  
  8. // Local includes
  9.  
  10. #include "digikam_export.h"
  11. #include "workerobject.h"
  12.  
  13. namespace Digikam
  14. {
  15.  
  16. class DIGIKAM_EXPORT ParallelWorkers
  17. {
  18.  
  19. public:
  20.  
  21.     /** ParallelWorkers is a helper class to distribute work over
  22.      *  several identical workers objects.
  23.      *  See ParallelAdapter for guidance how to use it.
  24.      */
  25.     ParallelWorkers();
  26.     virtual ~ParallelWorkers();
  27.  
  28.     /// The corresponding methods of all added worker objects will be called
  29.  
  30.     void schedule();
  31.     void deactivate(WorkerObject::DeactivatingMode mode = WorkerObject::FlushSignals);
  32.     void wait();
  33.  
  34.     void setPriority(QThread::Priority priority);
  35.  
  36.     /// Returns true if the current number of added workers has reached the optimalWorkerCount()
  37.     bool optimalWorkerCountReached() const;
  38.  
  39.     /** Regarding the number of logical CPUs on the current machine,
  40.         returns the optimal count of concurrent workers */
  41.     static int  optimalWorkerCount();
  42.  
  43. public:
  44.  
  45.     /// Connects signals outbound from all workers to a given receiver
  46.  
  47.     bool connect(const char* signal, const QObject* receiver, const char* method,
  48.                  Qt::ConnectionType type = Qt::AutoConnection) const;
  49.  
  50. protected:
  51.  
  52.     void add(WorkerObject* const worker);
  53.  
  54.     // Internal implementation
  55.  
  56.     // Replaces slot call distribution of the target QObject
  57.     int replacementQtMetacall(QMetaObject::Call _c, int _id, void** _a);
  58.     const QMetaObject *replacementMetaObject() const;
  59.     // Return the target QObject (double inheritance)
  60.     virtual QObject* asQObject() = 0;
  61.     // The qt_metacall of WorkerObject, one level above the target QObject
  62.     virtual int WorkerObjectQtMetacall(QMetaObject::Call _c, int _id, void** _a) = 0;
  63.     // The moc-generated metaObject of the target object
  64.     virtual const QMetaObject *mocMetaObject() const = 0;
  65.  
  66.     int replacementStaticQtMetacall(QMetaObject::Call _c, int _id, void **_a);
  67.     typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
  68.     virtual StaticMetacallFunction staticMetacallPointer() = 0;
  69.  
  70. protected:
  71.  
  72.     QList<WorkerObject*> m_workers;
  73.     int                  m_currentIndex;
  74.     QMetaObject*         m_replacementMetaObject;
  75.  
  76.     StaticMetacallFunction m_originalStaticMetacall;
  77. };
  78.  
  79. // -------------------------------------------------------------------------------------------------
  80.  
  81. template <class A>
  82.  
  83. class ParallelAdapter : public A, public ParallelWorkers
  84. {
  85. public:
  86.  
  87.     /**
  88.      * Instead of using a single WorkerObject, create a ParallelAdapter for
  89.      * your worker object subclass, and add() individual WorkerObjects.
  90.      * The load will be evenly distributed.
  91.      * Note: unlike with WorkerObject directly, there is no need to call schedule().
  92.      * For inbound connections (signals connected to a WorkerObject's slot, to be processed,
  93.      * use a Qt::DirectConnection on the adapter.
  94.      * For outbound connections (signals emitted from the WorkerObject),
  95.      * use ParallelAdapter's connect to have a connection from all added WorkerObjects.
  96.      */
  97.  
  98.     ParallelAdapter() {}
  99.     ~ParallelAdapter() {}
  100.  
  101.     void add(A* const worker) { ParallelWorkers::add(worker); }
  102.  
  103.     // Internal Implentation
  104.     // I know this is a hack
  105.  
  106.     int WorkerObjectQtMetacall(QMetaObject::Call _c, int _id, void** _a)
  107.         { return WorkerObject::qt_metacall(_c, _id, _a); }
  108.     const QMetaObject *mocMetaObject() const
  109.         { return A::metaObject(); }
  110.     static void qt_static_metacall(QObject* o, QMetaObject::Call _c, int _id, void **_a)
  111.         { static_cast<ParallelAdapter*>(o)->replacementStaticQtMetacall(_c, _id, _a); }
  112.     virtual StaticMetacallFunction staticMetacallPointer() { return qt_static_metacall; }
  113.  
  114.  
  115.     virtual const QMetaObject *metaObject() const
  116.         { return ParallelWorkers::replacementMetaObject(); }
  117.     virtual int qt_metacall(QMetaObject::Call _c, int _id, void** _a)
  118.         { return ParallelWorkers::replacementQtMetacall(_c, _id, _a); }
  119.  
  120.     virtual QObject* asQObject() { return this; }
  121.  
  122.     void schedule() { ParallelWorkers::schedule(); }
  123.     void deactivate(WorkerObject::DeactivatingMode mode = WorkerObject::FlushSignals)
  124.         { ParallelWorkers::deactivate(mode); }
  125.     void wait() { ParallelWorkers::wait(); }
  126.  
  127.     bool connect(const char* signal, const QObject* receiver, const char* method,
  128.                  Qt::ConnectionType type = Qt::AutoConnection) const
  129.         { return ParallelWorkers::connect(signal, receiver, method, type); }
  130. };
  131.  
  132. } // namespace Digikam
  133.  
  134. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement