Poco::BasicEvent

Poco::BasicEvent を紹介します。

Poco::BasicEvent は、内部で Poco::DefaultStrategy を使っており、任意の方法で delegate を呼び出します。1つの Poco::BasicEvent オブジェクトには、1つの method しか登録できず、複数を登録しようとすると、既にある delegate が上書きされます。

BasicEventTest.cpp

・TestBasicEvent() では、1つの Source から 3つの Target へイベントを飛ばし、Target::onEvent() で
 受信したイベントを表示。
・TestExpireingTarget() では、Poco::delegate の expireMillisecs 指定付きのものを呼び出し、expire 時間
 経過後にイベントを飛ばしても何も起きないことを確認。
・TestAsyncNotify() では、Poco::ActiveResult を使ってイベント受信を別スレッドで実行。

#include <Poco/BasicEvent.h>
#include <Poco/Delegate.h>
#include <Poco/Format.h>
 
#include <string>
#include <vector>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
 
const int kNumTargets = 3;
 
typedef struct
{
	ScopedLogMessage&	msg;
	int			val;
} TargetArgs;
 
class Source
{
public:
	Poco::BasicEvent<TargetArgs>	m_Event;
 
	Source()
	{
	}
 
	void notify(TargetArgs args)
	{
		m_Event(this, args);
	}
 
	std::string name(void) const
	{
		return std::string("source");
	}
};
 
class Target
{
public:
	Target(int id) :
		m_ID(id)
	{
	}
 
	void onEvent(const void* pSender, TargetArgs& args)
	{
		int valOriginal = args.val;
		++args.val;
		args.msg.Message(Poco::format(" Target[%d]::onEvent (got data=%d from %s -> %d)"
					, m_ID
					, valOriginal
					, const_cast<Source*>(reinterpret_cast<const Source*>(pSender))->name()
					, args.val));
	}
 
private:
	int	m_ID;
};
 
 
void TestBasicEvent(ScopedLogMessage& msg)
{
	msg.Message("--- Basic Event ---");
 
	Source source;
 
	std::vector<Target*> targets(kNumTargets);
	for(int i=0; i<kNumTargets; ++i)
	{
		targets[i] = new Target(i);
		source.m_Event += Poco::delegate(targets[i], &Target::onEvent);
	}
 
	TargetArgs args = {msg, 12};
 
	source.notify(args);
 
	for(int i=kNumTargets-1; i>=0; --i)
	{
		source.m_Event -= Poco::delegate(targets[i], &Target::onEvent);
		delete targets[i];
	}
}
 
void TestExpireingTarget(ScopedLogMessage& msg)
{
	msg.Message("--- Expireing Target ---");
 
	Source source;
	Target target(0);
 
	source.m_Event += Poco::delegate(&target, &Target::onEvent, 100);
 
	TargetArgs args = {msg, 34};
	source.notify(args);
 
	Poco::Thread::sleep(200);
 
	args.val = 56;
	source.notify(args);	// it's already expired -> no output
}
 
void TestAsyncNotify(ScopedLogMessage& msg)
{
	msg.Message("--- Async Notify ---");
 
	Poco::BasicEvent<TargetArgs>* pSource= reinterpret_cast<Poco::BasicEvent<TargetArgs>*>(new Source);
	Target target(0);
	(*pSource) += Poco::delegate(&target, &Target::onEvent);
 
	TargetArgs args = {msg, 78};
	Poco::ActiveResult<TargetArgs> retArg = pSource->notifyAsync(&target, args);
	delete pSource; // must work even when the event got deleted!
	pSource = NULL;
 
	retArg.wait();
}
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("BasicEventTest ", "start", "end");
 
	TestBasicEvent(msg);
	TestExpireingTarget(msg);
	TestAsyncNotify(msg);
 
	return 0;
}

Results of execution

・Async Notify の時は、別スレッドで実行されていることに注意。

[0] BasicEventTest start
[0] --- Basic Event ---
[0]  Target[0]::onEvent (got data=12 from source -> 13)
[0]  Target[1]::onEvent (got data=13 from source -> 14)
[0]  Target[2]::onEvent (got data=14 from source -> 15)
[0] --- Expireing Target ---
[0]  Target[0]::onEvent (got data=34 from source -> 35)
[0] --- Async Notify ---
[1]  Target[0]::onEvent (got data=78 from source -> 79)
[0] BasicEventTest end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年7月3日からのダウンロード数:839

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

http://pocoproject.org にある NotificationsEvents のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>