Cinder を久しぶりにチェックしたら、バージョンが地味に上がってた。
僕は普段openFrameworksを使っているのですが、ちょっとCinderも勉強してみることにしました。
で、まぁ基本的な機能はサンプルとか見ればわかるかなぁと思ったのですが、イベントだけちょっとわからなかったので、調べました。
oFでイベント
oFだと、
ofEvent<T>
ofNotifyEvent
ofAddListener
あたりを使えばよくて簡単(?)です。
ちなみにoFの場合はこれが参考になります
Cinderでは
- CallbackMgrを使う
- std::functionに入れた関数をコールバックにセットする
のがオススメなのかなー?
いまいちドキュメントもサンプルも見つからなかったのですが、OSCPackのCinder Blockがそれっぽいことをしていたので、参考にしました。Cinder内のblocks/OSC/src/OscListener.cpp参照。
一応ぼくが書いたコードも解説します。
class EventExampleApp : public AppNative {
public:
void setup();
void update();
void draw();
void keyDown( KeyEvent event );
CallbackMgr<void (MyEventArgs*)> cb;
void eventHandler(MyEventArgs *e);
CallbackId callbackId;
};
cbがコールバック関数を保存しとくオブジェクトのインスタンスで、eventHander(MyEventArgs *e)がfireされるようにコードを書いていきます。
void EventExampleApp::setup()
{
auto func = std::bind(&EventExampleApp::eventHandler, std::ref(*this), std::placeholders::_1);
callbackId = cb.registerCb(func);
// if you want to unregister, call
// cb.unregisterCb(callbackId);
}
一言で言えば、std::Function func に、メンバ関数を代入ということをしたいのですが、
難しいですね!
std::functionとかstd::bindとか、std:placeholdersとか、oFを書いてる分には使わなかった、新しいC++の機能を使いまくっています。
このへんは解説できるレベルにないので、まぁこうやったら動きました、という程度で。
oFはコミュニティが活発で、たくさんアドオンがあるのがいいのですが(ofxAddonsとか)、CinderはC++11の新機能とかもガンガン取り入れているので、書いてるうちにC++のレベルもあがりそうですね。
int cnt = 0;
void EventExampleApp::keyDown(cinder::app::KeyEvent event)
{
switch (event.getChar()) {
case KeyEvent::KEY_RETURN:
{
MyEventArgs e("Test " + cinder::toString<int>(++cnt));
cb.call(&e);
}
break;
default:
break;
}
}
cb.callでイベントをfireできます。
Enterキーを押すたびに、
eventHandler:Test 1
eventHandler:Test 2
eventHandler:Test 3
みたいなコンソールログがでます!