8. 异步操作

对于游戏开发而言,经常使用到异步相关操作,因此在使用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 这两点 。  


至此我们构建了一个初步的异步队列。以后其他各个模块均继承他们。 比如模块的初始化等

原文地址:https://www.cnblogs.com/riskyer/p/3323110.html