Toshihiro Shimizu 890ddd
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
/*!
Toshihiro Shimizu 890ddd
  \brief    The TFunctorInvoker is a singleton class that can be used to invoke functions
Toshihiro Shimizu 890ddd
            as Qt slots without having to inherit from QObject.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  \par Rationale
Toshihiro Shimizu 890ddd
              Signal and slots are an important part of the Qt framework - however, using them
Toshihiro Shimizu 890ddd
              requires to explicitly inherit from QObject. This singleton object is provided
Toshihiro Shimizu 890ddd
              to avoid the memory overhead of inheriting from QObject in the case of simple
Toshihiro Shimizu 890ddd
              function calls - notably functions that need to synchronize with Qt's main event
Toshihiro Shimizu 890ddd
              loop.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            \par Usage
Toshihiro Shimizu 890ddd
              Inherit from TFunctorInvoker::BaseFunctor and allocate a new 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
Toshihiro Shimizu 890ddd
              class MyFunctor : public TFunctorInvoker::BaseFunctor
Toshihiro Shimizu 890ddd
              {
Toshihiro Shimizu 890ddd
                MyParams m_params;                                // Function 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
              {
Toshihiro Shimizu 890ddd
                QMetaObject::invokeMethod(TFunctorInvoker::instance(), "invoke", 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
Toshihiro Shimizu 890ddd
class DVAPI TFunctorInvoker : public QObject
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Q_OBJECT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    \brief    Polymorphic base \a zerary functor for TFunctorInvoker-compatible
Toshihiro Shimizu 890ddd
              functors.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	class BaseFunctor
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		virtual ~BaseFunctor() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		virtual void operator()() = 0;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static TFunctorInvoker *instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void invokeQueued(BaseFunctor *functor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public Q_SLOTS:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void invoke(void *vPtr)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		BaseFunctor *func = (BaseFunctor *)vPtr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		(*func)();   // Invoke functor ...
Toshihiro Shimizu 890ddd
		delete func; // ... and then delete it
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	TFunctorInvoker() {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TFUNCTORINVOKER_H