对于游戏开发而言,经常使用到异步相关操作,因此在使用moduleframework之前应该提供一个异步操作的类。 以后相关的异步操作均继承这个类
AsyncOperation:
先贴出代码:
#ifndef __ASYNC_OPERATION_H__
#define __ASYNC_OPERATION_H__
#include <boost/function.hpp>
class AsyncOperation
{
public:
typedef boost::function(void<AsyncOperation*>) TypeOnExecute;
typedef boost::function(void<AsyncOperation*>) TypeOnComplete;
typedef boost::function(void<AsyncOperation*>) TypeOnAborted;
// 委托执行函数
explicit AsyncOperation(TypeOnExecute onExecute)
:_onExecute(onExecute)
{
if(!_onExecute) throw "onExecute is NULL";
}
virtual AsyncOperation(){}
void Execute(TypeOnComplete onComplete, TypeOnAborted onAorted = NULL)
{
if (!_onComplete) throw "onComplete is NULL"
_onComplete = onComplete;
_onAborted = onAorted;
_onExecute(this);
}
virtual void Abort()
{
}
void Complete()
{
_onComplete(this);
}
private:
TypeOnExecute _onExecute;
TypeOnComplete _onComplete;
TypeOnAborted _onAborted;
};
#endif
真正的执行函数是Execute 另外提供了一个完成 和终止的接口。
这个类应该比较简单。
在此类的基础上构建一个异步队列。 AsyncQueue继承该类
#ifndef __ASYNC_QUEUE_H__
#define __ASYNC_QUEUE_H__
#include <glog/logging.h>
#include "AsyncOpertaion.hpp"
#include <boost/bind.hpp>
#include <deque>
using namespace std;
class AsyncQueue : public AsyncQueue
{
public:
// 构造函数默认调用ExecuteNextChild来启动整个异步进程
AsyncQueue(): AsyncOperation(boost::bind(&AsyncQueue::ExecuteNextChild, this, _1))
, _abortFlag(false)
{
}
~AsyncQueue()
{
TypeOptQueue::iterator it = _queue.begin();
for (; it != _queue.end(); ++it)
{
delete *it;
}
}
// 加入队列
void Push(AsyncOperation* operation)
{
_queue.push_back(operation);
}
// 终止执行
void Abort()
{
if(_queue.empty()) return;
_abortFlag = true;
AsyncOperation* front = _queue.front();
front->Abort(); // 终止队列首位的执行
}
private:
void ExecuteNextChild(AsyncOperation* operation)
{
if(_queue.empty())
{
LOG(ERROR) << "Async Queue is Empty!";
return;
}
// 迭代执行_queue中的操作
AsyncOperation* front = _queue.front();
front->Execute(boost::bind(&AsyncQueue::OnChildComplete, this, _1));
}
void OnChildComplete(AsyncOperation* operation)
{
// 移除已执行的异步操作
_queue.pop_front();
delete operation;
if (_queue.empty())
{
// 通知队列执行完成
Complete();
return;
}
if (_abortFlag && _onAborted)
{
_onAborted(this);
}else
{
// 迭代执行
ExecuteNextChild(0);
}
}
private:
typedef deque<AsyncOperation*> TypeOptQueue; // 使用队列来包装
TypeOptQueue _queue;
bool _abortFlag;
};
#endif
这里一个巧妙指出在于 如果迭代执行整个异步队列, 注意看 构造函数和OnExecuteNextChild 这两点 。
至此我们构建了一个初步的异步队列。以后其他各个模块均继承他们。 比如模块的初始化等