はじめに
最近、JavaやObjective-Cでいわゆるオブザーバー・パターン(Observer pattern)を使う機会があったので、C++でもやってみたいと思い探していました。
すると、シグナル・スロットという仕組みを発見し、ちょうどBoostライブラリーによさそうなのがあったので試してみました。
何より、名前がちょっと格好いいですよね ←
シグナルとスロットとは何か?
シグナルとスロットとは何かというのが、まず、あやふやだったので調べました。
まあ、ぐぐっただけなので調べたうちには入らないので、あえて載せませんが・・・。
一言で言うと、Qtというプラットフォームでよく使われている通知を送る仕組みのようですね。
とりあえず試してみる
とりあえず、作ってみました!
demo_modelなるモデルがあり、状態が変わるとシグナルを発生して通知を送るというシチュエーションを妄想しています。
demo1.cpp
#include <iostream>
#include <boost/system/error_code.hpp>
#include <boost/signals2.hpp>
#include <boost/asio.hpp>
class demo_model
{
public:
demo_model(boost::asio::io_service& io_service)
: io_service_(io_service)
, timer_(io_service)
{}
boost::signals2::signal<void ()> signal;
void do_something()
{
timer_.expires_from_now(boost::posix_time::seconds(5));
timer_.async_wait([this](boost::system::error_code const& ec)
{
if (ec) return;
this->signal();
});
}
private:
boost::asio::io_service& io_service_;
boost::asio::deadline_timer timer_;
};
int main()
{
using namespace std;
boost::asio::io_service io_service;
demo_model m(io_service);
m.signal.connect([]{ cout << "Signalled! (1)" << endl; });
m.signal.connect([]{ cout << "Signalled! (2)" << endl; });
m.do_something();
io_service.run();
return 0;
}
ビルドに使ったbjamのプロジェクトファイル
Jamroot.jam
import testing ;
import os ;
BOOST_INCLUDE = [ os.environ BOOST_ROOT ] ;
run demo1.cpp
:
:
:
<include>$(BOOST_INCLUDE)
<toolset>clang:<cxxflags>-std=c++11
<toolset>gcc:<cxxflags>-std=gnu++0x
<define>BOOST_ERROR_CODE_HEADER_ONLY
;
5秒後に、Signalled!っていうのが表示されます。
使ってみて
特に、何かにはまることもなく簡単でした。
むしろ、Jamrootの書き方を思い出すのに苦労しました。
もし、需要があれば、サンプルで作ってみたプログラムの解説もしてみようと思います。