Last active
August 29, 2015 14:08
-
-
Save meki/8426b8643f038340eb25 to your computer and use it in GitHub Desktop.
クラスにリスナインターフェースとオブザーバリストメンバ変数を追加するマクロ ref: http://qiita.com/_meki/items/b631e8f51aa8db00ff9e
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
class Foo extends View.OnClickListener { |
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
class Bar : public Foo::OnDoSomethingListener { | |
void onDoSomething(const Foo& f) | |
{ | |
// f が do something したら Bar も何かやる | |
} | |
} | |
/* 何かの処理 */ { | |
Bar bar1; | |
Bar bar2; | |
Foo foo; | |
// bar1, bar2 を foo のリスナーとして登録 | |
foo.setUpdateListener(bar1); | |
foo.setUpdateListener(bar2); | |
foo.doSomething(); | |
// ここで bar1, bar2 の onDoSomethingListener が呼ばれる | |
} | |
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
class Foo { | |
public: | |
//! Foo の DoSomething を監視するクラスのインターフェース | |
class DoSomethingListener { | |
public: | |
//! アップデート受信のための関数. | |
virtual void onDoSomething(const Foo & obj) = 0; | |
}; | |
// スマートポインタをついでに typedef しておく | |
typedef std::shared_ptr<DoSomethingListener> | |
PtrDoSomethingListener; | |
//! リスナー登録. | |
void setDoSomethingListener(const PtrDoSomethingListener& p) { | |
listDoSomethingListener.push_back(p); | |
} | |
private: | |
//! Update を通知. | |
void notifyDoSomething() { | |
for(auto p : listDoSomethingListener) { | |
p->onDoSomething(*this); | |
} | |
} | |
//! 登録されているリスナーのリスト | |
std::vector<PtrDoSomethingListener> listDoSomethingListener; | |
} | |
class Bar : public Foo::OnDoSomethingListener { | |
public: | |
void onDoSomething(const Foo& obj) override {} | |
} |
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 <iostream> | |
#include <string> | |
#include <memory> | |
#include <vector> | |
using namespace std; | |
class Aniki { | |
// テンプレ | |
public: | |
class YaranaikaListener { | |
public: | |
virtual void onYaranaika(const Aniki& obj) = 0; | |
}; | |
typedef shared_ptr<YaranaikaListener> PtrYaranaikaListener; | |
void setYaranaikaListener(const PtrYaranaikaListener& p) { | |
listYaranaikaListener.push_back(p); | |
} | |
private: | |
void notifyYaranaika() { | |
for(auto p : listYaranaikaListener) { | |
p->onYaranaika(*this); | |
} | |
} | |
std::vector<PtrYaranaikaListener> listYaranaikaListener; | |
// Aniki クラス個別の処理 | |
public: | |
Aniki(const string& name) : m_name(name) {} | |
void yaranaika() { | |
cout << m_name << ": やらないか" << endl; | |
// やらないかをリスナーに通知 | |
notifyYaranaika(); | |
} | |
const string& getName() const { return m_name; } | |
private: | |
string m_name; | |
}; | |
class Shatei : public Aniki::YaranaikaListener { | |
public: | |
Shatei(string name) : m_name(name) {} | |
void onYaranaika(const Aniki& obj) override | |
{ | |
cout << m_name << ": " << obj.getName() << "兄貴ィィッ-----!" << endl; | |
} | |
private: | |
string m_name; | |
}; | |
typedef shared_ptr<Shatei> PtrShatei; | |
int main() { | |
// 舎弟を作成 | |
PtrShatei a(new Shatei("アドン")); | |
PtrShatei s(new Shatei("サムソン")); | |
PtrShatei u(new Shatei("うみにん")); | |
// アニキを作成 | |
Aniki aniki("イダテン"); | |
// 舎弟を登録 | |
aniki.setYaranaikaListener(a); | |
aniki.setYaranaikaListener(s); | |
aniki.setYaranaikaListener(u); | |
// やらないか | |
aniki.yaranaika(); | |
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
イダテン: やらないか | |
アドン: イダテン兄貴ィィッ-----! | |
サムソン: イダテン兄貴ィィッ-----! | |
うみにん: イダテン兄貴ィィッ-----! |
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
//! クラスの冒頭に書くとリスナインターフェースとオブザーバリストを追加できるマクロ | |
//! @param _class クラス名 | |
//! @param _what イベント名, On[_what]Listener というインターフェースが追加される. | |
#define REGISTER_LISTENER(_class, _what) \ | |
public: \ | |
class _what ## Listener { \ | |
public: \ | |
virtual void on ## _what (const _class & obj) = 0; \ | |
}; \ | |
\ | |
typedef std::shared_ptr< _what ## Listener > Ptr ## _what ## Listener; \ | |
\ | |
void set ## _what ## Listener(const Ptr ## _what ## Listener& p) { \ | |
list ## _what ## Listener.push_back(p); \ | |
} \ | |
\ | |
private: \ | |
void notify ## _what () { \ | |
for(auto p : list ## _what ## Listener) { \ | |
p->on ## _what (*this); \ | |
} \ | |
} \ | |
std::vector<Ptr ## _what ## Listener> list ## _what ## Listener; | |
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
class Aniki { | |
// OnYaranaikaListener を追加 | |
REGISTER_LISTENER(Aniki, Yaranaika) | |
// OnLoveListener を追加 | |
REGISTER_LISTENER(Aniki, Love) | |
public: | |
Aniki(const string& name) : m_name(name) {} | |
void yaranaika() { | |
cout << m_name << ": やらないか" << endl; | |
notifyYaranaika(); // 通知 1 | |
} | |
void love() { | |
cout << m_name << ": 愛・・・" << endl; | |
notifyLove(); // 通知 2 | |
} | |
const string& getName() const { return m_name; } | |
private: | |
string m_name; | |
}; | |
class Shatei : public Aniki::YaranaikaListener, public Aniki::LoveListener | |
{ | |
public: | |
Shatei(const string& name) : m_name(name) {} | |
// イベント受信 1 | |
void onYaranaika(const Aniki& obj) override { | |
cout << m_name << ": " << obj.getName() << "兄貴ィィッ-----!" << endl; | |
} | |
// イベント受信 2 | |
void onLove(const Aniki& obj) override { | |
cout << m_name << ": " << "超兄貴!" << endl; | |
} | |
private: | |
string m_name; | |
}; | |
typedef shared_ptr<Shatei> PtrShatei; | |
int main() { | |
Aniki aniki("イダテン"); | |
PtrShatei a(new Shatei("アドン")); | |
PtrShatei s(new Shatei("サムソン")); | |
PtrShatei u(new Shatei("うみにん")); | |
// 舎弟を登録 1 | |
aniki.setYaranaikaListener(a); | |
aniki.setYaranaikaListener(s); | |
aniki.setYaranaikaListener(u); | |
// アニキがアクション 1 | |
aniki.yaranaika(); | |
cout << endl; | |
// 舎弟を登録 2 | |
aniki.setLoveListener(a); | |
aniki.setLoveListener(s); | |
aniki.setLoveListener(u); | |
// アニキがアクション 2 | |
aniki.love(); | |
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
イダテン: やらないか | |
アドン: イダテン兄貴ィィッ-----! | |
サムソン: イダテン兄貴ィィッ-----! | |
うみにん: イダテン兄貴ィィッ-----! | |
イダテン: 愛・・・ | |
アドン: 超兄貴! | |
サムソン: 超兄貴! | |
うみにん: 超兄貴! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment