root/trunk/0038_BasicEvent/BasicEventTest.cpp

User picture

Author: Setsu

Revision: 348 («Previous)


File Size: 5.22 KB

(July 02, 2010 19:16 UTC) Almost 2 years ago

Function name changed.

 
Show/hide line numbers
//
//  BasicEventTest.cpp
//
//  Created by Setsu on 7/2/10.
//  Copyright 2010 RoundSquare Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

//----------------------------------------
//	include
//----------------------------------------
#include <Poco/Logger.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/BasicEvent.h>
#include <Poco/Delegate.h>
#include <Poco/Format.h>

#include <string>
#include <vector>

#include "ScopedLogMessage.h"

//----------------------------------------
//	const
//----------------------------------------
const int kNumTargets = 3;

//----------------------------------------
//	typedef
//----------------------------------------
typedef struct
{
	ScopedLogMessage&	msg;
	int					val;
} TargetArgs;

//----------------------------------------
//	Source
//----------------------------------------
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");
	}
};

//----------------------------------------
//	Target
//----------------------------------------
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;
};


//----------------------------------------
//	TestBasicEvent
//----------------------------------------
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];
	}
}

//----------------------------------------
//	TestExpireingTarget
//----------------------------------------
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
}

//----------------------------------------
//	TestAsyncNotify
//----------------------------------------
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();
}

//----------------------------------------
//	PrepareConsoleLogger
//----------------------------------------
void PrepareConsoleLogger(const std::string& name, int level=Poco::Message::PRIO_INFORMATION)
{
	Poco::FormattingChannel* pFCConsole = new Poco::FormattingChannel(new Poco::PatternFormatter("%t"));
	pFCConsole->setChannel(new Poco::ConsoleChannel);
	pFCConsole->open();

	Poco::Logger::create(name, pFCConsole, level);
}

//----------------------------------------
//	main
//----------------------------------------
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);

	ScopedLogMessage msg("BasicEventTest ", "start", "end");

	TestBasicEvent(msg);
	TestExpireingTarget(msg);
	TestAsyncNotify(msg);

	return 0;
}