На момент описания данного модуля готово 3 типа делегатов - без параметров, с одним и двумя параметрами. Для статических функций и методов класса также определены разные классы делегатов, но имеющие один интерфейс.
Интерфейс делегата без входных параметров:
class mliDelegateVoid
{
public:
virtual ~mliDelegateVoid(){};
inline virtual void run()=0;
inline virtual void operator ()()=0;
inline virtual bool operator==(const mliDelegateVoid & other)const =0;
inline virtual bool operator!=(const mliDelegateVoid & other)const =0;
};
Интерфейс делегата с одним параметром:
template <class parameter>
class mliDelegateOne
{
public:
virtual ~mliDelegateOne(){};
inline virtual void run (parameter pParameter)=0;
inline virtual void operator ()(parameter pParameter)=0;
inline virtual bool operator==(const mliDelegateOne<parameter> & other)const =0;
inline virtual bool operator!=(const mliDelegateOne<parameter> & other)const =0;
};
Интерфейс делегата с двумя параметрами:
template <class one, class two>
class mliDelegateTwo
{
public:
virtual ~mliDelegateTwo(){};
inline virtual void run (one One, two Twor)=0;
inline virtual void operator ()(one One, two Two)=0;
inline virtual bool operator==(const mliDelegateTwo<one, two> & other)const =0;
inline virtual bool operator!=(const mliDelegateTwo<one, two> & other)const =0;
};
Все методы понятны и без описание, нет смысла описывать. У каждого делегата по возможности сохраняется схожий интерфейс. Исключения составляют методы вызова и создание делегатов. Создание происходит посредством функций-фабрик:
Фабрика создания делегата функции без параметров
inline mliDelegateVoid * mlBuildDelegate
(mlDelegateCVoid::tFunction pFunction);
Фабрика создания делегата метода класса без параметров
template <class CLASS>
inline mliDelegateVoid * mlBuildDelegate
(CLASS * pClass, typename mlDelegateMVoid<CLASS>::method pMethod);
Фабрика создания делегата функции c одним параметром
template <class parameter>
inline mliDelegateOne<parameter>* mlBuildDelegate
(typename mlDelegateCOne<parameter>::tFunction pFunction);
Фабрика создания делегата метода класса c одним параметром
template <class CLASS, class parameter>
inline mliDelegateOne<parameter>* mlBuildDelegate
(CLASS * pClass, typename mlDelegateMOne<CLASS, parameter>::method pFunction);
Фабрика создания делегата функции c двумя параметрами
template <class one, class two>
inline mliDelegateTwo<one, two>* mlBuildDelegate
(typename mlDelegateCTwo<one, two>::tFunction pFunction);
Фабрика создания делегата метода класса c двумя параметрами
template <class CLASS, class one, class two>
inline mliDelegateTwo<one, two>* mlBuildDelegate
(CLASS * pClass, typename mlDelegateMTwo<CLASS, one, two>::method pFunction);
Также определена очередь вызовов делегатов:
class **mlDelegateVoidDeque**
template <class parameter> class **mlDelegateOneDeque**
template <class one, class two> class **mlDelegateTwoDeque**
Как и в случае с делегатами, у очередей сохранен общий интерфейс:
class mlDelegateVoidDeque
{
public:
virtual void add(mliDelegateVoid * pDelegate);
virtual void remove(mliDelegateVoid * pDelegate);
virtual void clear();
void operator += (mliDelegateVoid * pDelegate);
void operator -= (mliDelegateVoid * pDelegate);
void operator ()();
};
Описание методов:
void add(mliDelegateVoid * pDelegate);
void remove(mliDelegateVoid * pDelegate);
void clear();
void operator += (mliDelegateVoid * pDelegate);
void operator -= (mliDelegateVoid * pDelegate);
void operator ()();
Пример использования делегатов:
#include "mlDelegate.h"
#include <iostream>
class TestDelegate
{
public:
static void statMethodVoid()
{
std::cout<<std::endl<<"statMethodVoid";
}
static void statMethodFloat(double var)
{
std::cout<<std::endl<<"statMethodFloat. param = "<<var;
}
static void statMethodFloat2(double var, int var2)
{
std::cout<<std::endl<<"statMethodFloat2. param = "<<var<<"param2 = "<<var2;
}
void methodFloat2(double var, int var2)
{
std::cout<<std::endl<<"methodFloat2. param = "<<var<<"param2 = "<<var2;
}
void methodVoid()
{
std::cout<<std::endl<<"methodVoid";
}
void methodFloat(double var)
{
std::cout<<std::endl<<"methodFloat. param = "<<var;
}
};
int main()
{
TestDelegate object;
mlDelegateVoidDeque dequeDelegates;
mlDelegateOneDeque<double> dequeOnes;
mlDelegateTwoDeque<double, int> dequeTwo;
mliDelegateVoid *d0 = mlBuildDelegate(TestDelegate::statMethodVoid);
mliDelegateVoid *d1 = mlFactory(&object, &TestDelegate::methodVoid);
mliDelegateOne<double> * c0 =
mlFactory<double>(TestDelegate::statMethodFloat);
mliDelegateOne<double> * c1 =
mlFactory<TestDelegate, double>(&object, &TestDelegate::methodFloat);
mliDelegateTwo<double, int> * t0 =
mlFactory<double, int>(TestDelegate::statMethodFloat2);
mliDelegateTwo<double, int> * t1 =
mlFactory<TestDelegate, double, int>(&object, &TestDelegate::methodFloat2);
dequeDelegates += d0;
dequeDelegates += d1;
dequeOnes += c0;
dequeOnes += c1;
dequeTwo += t0;
dequeTwo += t1;
dequeDelegates();
dequeOnes (1);
dequeTwo (1, 2);
return 0;
}
Вывод:
statMethodVoid
methodVoid
statMethodFloat. param = 1
methodFloat. param = 1
statMethodFloat2. param = 1param2 = 2
methodFloat2. param = 1param2 = 2