现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

一个简单的C++延迟调用系统

2012-09-13 21:42 工业·编程 ⁄ 共 2172字 ⁄ 字号 暂无评论

// object.h

#include <boost/function.hpp>

#include <boost/bind.hpp>

#include <map>

#include <string>

class FObject

{

public:

typedef boost::function<void()>  EventFunction;

struct EventParam

{

std::string   strEvent;

EventFunction eventFunc;

float         fDeltaTime;

mutable float CurrentTime;

bool          bLoop;

};

typedef std::map<std::string, EventParam>   EventMap;

public:

virtual ~FObject();

virtual void                Tick( float fDeltaTime );

public:

void                        ScheduleEvent( const std::string& strEvent, float fDeltaTime, bool bLoop, EventFunction EventFunc );

bool                        IsEventActive( const std::string& strEvent ) const;

void                        KillEvent( const std::string& strEvent );

#define SCHEDULE_EVENT( DeltaTime, bLoop, nameFunc ) \

ScheduleEvent( #nameFunc, DeltaTime, bLoop, boost::bind( nameFunc, this ) )

#define SCHEDULE_KILL( nameFunc ) \

KillEvent( #nameFunc )

private:

EventMap                    m_Events;

};

// object.cpp

#include "Object.h"

FObject::~FObject()

{

}

void FObject::Tick( float fDeltaTime )

{

for( EventMap::iterator it = m_Events.begin();

it != m_Events.end();

)

{

it->second.CurrentTime -= fDeltaTime;

if( it->second.CurrentTime <= 0.0f )

{

if( it->second.eventFunc )

{

it->second.eventFunc();

}

if( !it->second.bLoop )

{

it = m_Events.erase(it);

}

else

{

it->second.CurrentTime = it->second.fDeltaTime;

++it;  // this is very important

}

}

else

{

++it; // this is very important

}

}

}

void FObject::ScheduleEvent( const std::string& strEvent, float fDeltaTime, bool bLoop, EventFunction EventFunc )

{

EventParam Param;

Param.strEvent = strEvent;

Param.fDeltaTime = fDeltaTime;

Param.CurrentTime = fDeltaTime;

Param.eventFunc = EventFunc;

Param.bLoop = bLoop;

EventMap::iterator itPos = m_Events.find( strEvent );

if( itPos != m_Events.end() )

{

itPos->second = Param;

}

else

{

m_Events.insert( std::make_pair( strEvent, Param ) );

}

}

bool FObject::IsEventActive( const std::string& strEvent ) const

{

return m_Events.find( strEvent ) != m_Events.end();

}

void FObject::KillEvent( const std::string& strEvent )

{

EventMap::iterator itPos = m_Events.find( strEvent );

if( itPos != m_Events.end() )

{

m_Events.erase(itPos);

}

}

      // 够简单吧,这个只是把函数对象保存下来的办法。通常只应该用在本Object身上,这样当本Object失效之后所有的延迟调用都会失效。缺陷就是每个Object都需要被tick才可以支持。可选的方案还可以创建一个用于统一管理的ScheduleManager,这样只需要tick manager就可以了,这个方案的缺陷可能会调用到已经不存在的Object的方法导致崩溃。

      这个姑且如此,能用了。先就这样,有问题再说。嘿嘿。

给我留言

留言无头像?