Created
March 28, 2016 21:11
-
-
Save TABETA/7418918c3182606624a5 to your computer and use it in GitHub Desktop.
メンバ関数ポインタへのコールバックをtemplateで ref: http://qiita.com/abedominal/items/9cca99e10cf4eac1708f
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "Singleton.hpp" | |
using namespace std; | |
struct Listner | |
{ | |
public: | |
Listner() {} | |
virtual ~Listner(){} | |
virtual void execute() = 0; | |
}; | |
enum ListnerName | |
{ | |
Listner_start = -1, | |
Listner1_event1 = 0, | |
Listner1_event2, | |
Listner_end, | |
}; | |
class Caster | |
{ | |
public: | |
Caster() | |
{ | |
} | |
bool initialize() | |
{ | |
return initialize<Listner_start>(); | |
} | |
void run() | |
{ | |
for (int i = 0; i < Listner_end; ++i) | |
{ | |
listners_[i]->execute(); | |
} | |
} | |
~Caster() | |
{ | |
for (int i = 0; i < Listner_end; ++i) | |
{ | |
delete listners_[i]; | |
} | |
} | |
private: | |
template<ListnerName N> | |
bool initialize(); | |
template<> | |
bool initialize<Listner_start>() | |
{ | |
const ListnerName next = static_cast<ListnerName>(Listner_start + 1); | |
return initialize<next>(); | |
} | |
template<> | |
bool initialize<Listner_end>() | |
{ | |
return true; | |
} | |
template <typename T> | |
class ConcreteListner : public Listner | |
{ | |
public: | |
ConcreteListner(void(T::*func)()) | |
: func_(func) {} | |
~ConcreteListner(){} | |
void execute() { (T::getInstance()->*func_)(); } | |
private: | |
void (T::*func_)(); | |
}; | |
Listner* listners_[Listner_end]; | |
}; | |
template<ListnerName N> struct listner_traits; | |
template<ListnerName N> | |
bool Caster::initialize() | |
{ | |
if ((listners_[N] = new(std::nothrow) ConcreteListner<listner_traits<N>::object_t>(listner_traits<N>::cb)) == 0) | |
{ | |
return false; | |
} | |
return initialize<static_cast<ListnerName>(N+1)>(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <iostream> | |
#include "Singleton.hpp" | |
using namespace std; | |
class Listner1 : public Singleton<Listner1> | |
{ | |
public: | |
void event1() | |
{ | |
cout << "event1" << endl; | |
} | |
void event2() | |
{ | |
cout << "event2" << endl; | |
} | |
}; | |
template<> | |
struct listner_traits<Listner1_event1> | |
{ | |
typedef Listner1 object_t; | |
typedef void(Listner1::*callBack)(); | |
static const callBack cb; | |
}; | |
const listner_traits<Listner1_event1>::callBack listner_traits<Listner1_event1>::cb = &Listner1::event1; | |
template<> | |
struct listner_traits<Listner1_event2> | |
{ | |
typedef Listner1 object_t; | |
typedef void(Listner1::*callBack)(); | |
static const callBack cb; | |
}; | |
const listner_traits<Listner1_event2>::callBack listner_traits<Listner1_event2>::cb = &Listner1::event2; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Singleton.hpp" | |
#include "Caster.hpp" | |
#include "Listner1.hpp" | |
using namespace std; | |
int main(int argv, char* argc[]) | |
{ | |
Caster caster; | |
caster.initialize(); | |
caster.run(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
template <typename T> | |
class Singleton | |
{ | |
protected: | |
Singleton(){} | |
Singleton(Singleton const&); | |
~Singleton(){} | |
Singleton& operator=(Singleton const&); | |
public: | |
static T* getInstance() | |
{ | |
static T i; | |
return &i; | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment