zoukankan      html  css  js  c++  java
  • 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 这两点 。  


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

  • 相关阅读:
    for、foreach、stream 哪家的效率更高,你真的用对了吗?
    SQL中那么多函数,Java8为什么还要提供重复的Stream方法,多此一举?
    Java中对象池的本质是什么?(实战分析版)
    引入 Gateway 网关,这些坑一定要学会避开!!!
    Java8 Stream流式编程,极大解放你的生产力!
    backup.bat
    robocopy用法详解
    【转】MYSQL中的COLLATE是什么?
    Java实现自定义监控系统,秀不秀?
    IDEA激活码2021永久,全网唯一靠谱的免费激活IDEA的方式!!!
  • 原文地址:https://www.cnblogs.com/riskyer/p/3323110.html
Copyright © 2011-2022 走看看