Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TFUNCTORINVOKER_H
Toshihiro Shimizu 890ddd
#define TFUNCTORINVOKER_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tcommon.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qobject></qobject>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    TFunctorInvoker  declaration
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  \brief    The TFunctorInvoker is a singleton class that can be used to invoke
Shinya Kitaoka 120a6e
functions
Toshihiro Shimizu 890ddd
            as Qt slots without having to inherit from QObject.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  \par Rationale
Shinya Kitaoka 120a6e
              Signal and slots are an important part of the Qt framework -
Shinya Kitaoka 120a6e
however, using them
Shinya Kitaoka 120a6e
              requires to explicitly inherit from QObject. This singleton object
Shinya Kitaoka 120a6e
is provided
Shinya Kitaoka 120a6e
              to avoid the memory overhead of inheriting from QObject in the
Shinya Kitaoka 120a6e
case of simple
Shinya Kitaoka 120a6e
              function calls - notably functions that need to synchronize with
Shinya Kitaoka 120a6e
Qt's main event
Toshihiro Shimizu 890ddd
              loop.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            \par Usage
Shinya Kitaoka 120a6e
              Inherit from TFunctorInvoker::BaseFunctor and allocate a new
Shinya Kitaoka 120a6e
instance on the heap,
Toshihiro Shimizu 890ddd
              to be supplied to the TFunctorInvoker::invoke() slot.
Toshihiro Shimizu 890ddd
\n
Toshihiro Shimizu 890ddd
              The following code exemplifies a correct usage for this class:
Toshihiro Shimizu 890ddd
\n
Toshihiro Shimizu 890ddd
              \code
Shinya Kitaoka d1f6c4
              class MyFunctor final : public TFunctorInvoker::BaseFunctor
Toshihiro Shimizu 890ddd
              {
Shinya Kitaoka 120a6e
                MyParams m_params;                                // Function
Shinya Kitaoka 120a6e
parameters
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              public:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
                MyFunctor(const MyParams& params) : m_params(params) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
                void operator()()
Toshihiro Shimizu 890ddd
                {
Toshihiro Shimizu 890ddd
                  // The function body, operating on m_params
Toshihiro Shimizu 890ddd
                }
Toshihiro Shimizu 890ddd
              };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              //------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              void invokeMyFunctor_queued(const MyParams& params)
Toshihiro Shimizu 890ddd
              {
Shinya Kitaoka 120a6e
                QMetaObject::invokeMethod(TFunctorInvoker::instance(), "invoke",
Shinya Kitaoka 120a6e
Qt::QueuedConnection,
Toshihiro Shimizu 890ddd
                  Q_ARG(void*, new MyFunctor(params))
Toshihiro Shimizu 890ddd
                );
Toshihiro Shimizu 890ddd
              }
Toshihiro Shimizu 890ddd
              \endcode
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class DVAPI TFunctorInvoker final : public QObject {
Shinya Kitaoka 120a6e
  Q_OBJECT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\brief    Polymorphic base \a zerary functor for TFunctorInvoker-compatible
Shinya Kitaoka 120a6e
        functors.
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  class BaseFunctor {
Shinya Kitaoka 120a6e
  public:
Shinya Kitaoka 120a6e
    virtual ~BaseFunctor() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    virtual void operator()() = 0;
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TFunctorInvoker *instance();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void invokeQueued(BaseFunctor *functor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public Q_SLOTS:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void invoke(void *vPtr) {
Shinya Kitaoka 120a6e
    BaseFunctor *func = (BaseFunctor *)vPtr;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    (*func)();    // Invoke functor ...
Shinya Kitaoka 120a6e
    delete func;  // ... and then delete it
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TFunctorInvoker() {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TFUNCTORINVOKER_H