您的位置:首页 > 编程语言 > C语言/C++

C++ 事件机制实现

2013-05-08 20:53 381 查看
一. 先看看事件接口和实现

#ifndef IEVENT_H

#define IEVENT_H

/*

以下各基础设施是在C++中事件机制的完整实现,事件是面向组件开发的必要特性之一。

最开始打算用函数指针模拟事件,但由于C++中成员函数指针不能和void*相互强转,而且

typedef中不能含有模板,所以才不得已以接口继承实现。这样效果也不错 :)

创 作 者:sky

时 间:2005.06.22

修订时间:2005.06.22

*/

#include "../Collection/SafeArrayList.h"

template<class SenderType ,class ParaType> class EventPublisher ;

class NullType

{

};

// IEventHandler 是事件处理句柄,预定事件的类从此接口继承以实现事件处理函数

template<class SenderType ,class ParaType>

interface IEventHandler

{

public:

virtual ~IEventHandler(){}

private:

virtual void HandleEvent(SenderType sender ,ParaType para) = 0 ;

friend class EventPublisher<SenderType ,ParaType> ;

};

// IEvent 事件预定方通过此接口预定事件

template<class SenderType ,class ParaType>

interface IEvent

{

public:

virtual ~IEvent(){}

virtual void Register (IEventHandler<SenderType ,ParaType>* handler) = 0 ;

virtual void UnRegister(IEventHandler<SenderType ,ParaType>* handler) = 0 ;

};

// IEventActivator 事件发布方通过此接口触发事件

template<class SenderType ,class ParaType>

interface IEventActivator

{

public:

virtual ~IEventActivator(){}

virtual void Invoke(SenderType sender ,ParaType para) = 0;

virtual int HandlerCount() = 0;

virtual IEventHandler<SenderType ,ParaType>* GetHandler(int index) = 0;

};

// IEventPublisher 事件发布方发布事件相当于就是发布一个IEventPublisher派生类的对象

// 不过仅仅将该对象的IEvent接口发布即可。

template<class SenderType ,class ParaType>

interface IEventPublisher : public IEvent<SenderType ,ParaType> ,public IEventActivator<SenderType ,ParaType>

{

};

// EventPublisher是IEventPublisher的默认实现

template<class SenderType ,class ParaType>

class EventPublisher :public IEventPublisher<SenderType ,ParaType>

{

private:

SafeArrayList< IEventHandler<SenderType ,ParaType> > handerList ;

IEventHandler<SenderType ,ParaType>* innerHandler ;

public:

void Register(IEventHandler<SenderType ,ParaType>* handler)

{

this->handerList.Add(handler) ;

}

void UnRegister(IEventHandler<SenderType ,ParaType>* handler)

{

this->handerList.Remove(handler) ;

}

void Invoke(SenderType sender ,ParaType para)

{

int count = this->handerList.Count() ;

for(int i=0 ;i<count ;i++)

{

IEventHandler<SenderType ,ParaType>* handler = this->handerList.GetElement(i) ;

handler->HandleEvent(sender ,para) ;

}

}

int HandlerCount()

{

return this->handerList.Count() ;

}

IEventHandler<SenderType ,ParaType>* GetHandler(int index)

{

return this->handerList.GetElement(index) ;

}

};

#endif

二. 一个定时器类Timer,演示如何发布事件。想必大家都知道定时器的用途了哦,这个Timer就像C#中的Timer类一样。

#ifndef TIMER_H

#define TIMER_H

/*

Timer 定时器,每经过一段指定时间就触发事件

创 作 者:sky

时 间:2005.06.22

修订时间:2005.06.22

*/

#include "IEvent.h"

#include "Thread.h"

void TimerThreadStart(void* para) ;

class Timer

{

private:

int spanInMillSecs ;

volatile bool isStop ;

volatile bool timerThreadDone ;

public:

friend void TimerThreadStart(void* para) ;

IEvent<Timer* ,NullType>* TimerTicked ;

Timer(int span_InMillSecs)

{

this->isStop = true ;

this->timerThreadDone = true ;

this->spanInMillSecs = span_InMillSecs ;

this->TimerTicked = new EventPublisher<Timer* ,NullType> ;

}

~Timer()

{

this->Stop() ;

delete this->TimerTicked ;

}

void Start()

{

if(! this->isStop)

{

return ;

}

this->isStop = false ;

Thread thread ;

thread.Start(TimerThreadStart ,this) ;

//unsigned int dwThreadId ;

//HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0 , (unsigned int (_stdcall*)(void*))&TimerThreadStart , this, 0, &dwThreadId);

}

void Stop()

{

if( this->isStop)

{

return ;

}

this->isStop = true ;

//等待工作线程退出

while(! this->timerThreadDone)

{

Sleep(200) ;

}

}

private:

void WorkerThread()

{

this->timerThreadDone = false ;

while(! this->isStop)

{

Sleep(this->spanInMillSecs) ;

if(this->isStop)

{

break ;

}

NullType nullObj ;

((EventPublisher<Timer* ,NullType>*)this->TimerTicked)->Invoke(this ,nullObj) ;

}

this->timerThreadDone = true ;

}

};

void TimerThreadStart(void* para)

{

Timer* timer = (Timer*)para ;

timer->WorkerThread() ;

}

#endif

三. 预定事件例子

class TimerEventExample :public IEventHandler<Timer* ,NullType> ,CriticalSection

{

private:

Timer* timer ;

public:

TimerEventExample(int checkSpan)

{

this->timer = new Timer(checkSpan) ;

this->timer->TimerTicked->Register(this) ;

}

~TimerEventExample()

{

delete this->timer ;

}

private:

//处理定时事件

void HandleEvent(Timer* sender ,NullType para)

{

cout<<"Time ticked !"<<endl ;

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: