C++ 事件机制实现

一. 先看看事件接口和实现

#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 ;
 }
};

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值