简易版GameFramework游戏框架搭建教程(八)Task

在框架中,Web请求,资源的下载或加载会以任务的形式进行处理,Task作为框架的基础功能,所负责管理的就是这三类任务

打开工程,在Base文件夹下新建一个Task文件夹,并新建3个类文件


其中

ITask是任务接口,主要存储任务执行时所需的数据

ITaskAgent是任务代理接口,负责对任务进行处理(实际的处理逻辑则通过调用具体模块的代理辅助器执行,这一点在后面编写需要使用任务功能的模块时会涉及到)

TaskPool是任务池,使用链表与栈来维护任务与任务代理,并提供任务的添加与移除等操作


打开ITask,将其修改为接口,然后添加2个属性就可以了

/// <summary>
/// 任务接口
/// </summary>
public interface ITask{

    /// <summary>
    /// 任务序列ID
    /// </summary>
    int SerialId { get; }

    /// <summary>
    /// 任务是否完成
    /// </summary>
    bool Done { get; }

}

在具体的模块中,会根据需求建立实现该接口的Task类


打开ITaskAgent类,将其也修改为接口,添加泛型与约束

/// <summary>
/// 任务代理接口
/// </summary>
/// <typeparam name="T">任务类型</typeparam>
public interface ITaskAgent<T> where T : ITask {

}

然后添加属性与方法

    /// <summary>
    /// 获取任务。
    /// </summary>
    T Task { get; }

    /// <summary>
    /// 初始化任务代理。
    /// </summary>
    void Initialize();

    /// <summary>
    /// 任务代理轮询。
    /// </summary>
    void Update(float elapseSeconds, float realElapseSeconds);

    /// <summary>
    /// 关闭并清理任务代理。
    /// </summary>
    void Shutdown();

    /// <summary>
    /// 开始处理任务。
    /// </summary>
    /// <param name="task">要处理的任务。</param>
    void Start(T task);

    /// <summary>
    /// 停止正在处理的任务并重置任务代理。
    /// </summary>
    void Reset();


最后打开TaskPool类,为其添加泛型与约束

/// <summary>
/// 任务池
/// </summary>
/// <typeparam name="T">任务类型</typeparam>
public class TaskPool<T> where T : ITask{

}

添加字段与属性,并在构造方法里进行初始化

    /// <summary>
    /// 可用任务代理
    /// </summary>
    private Stack<ITaskAgent<T>> m_FreeAgents;

    /// <summary>
    /// 工作中任务代理
    /// </summary>
    private LinkedList<ITaskAgent<T>> m_WorkingAgents;

    /// <summary>
    /// 等待中任务
    /// </summary>
    private LinkedList<T> m_WaitingTasks;

    /// <summary>
    /// 可用任务代理数量
    /// </summary>
    public int FreeAgentCount { get { return m_FreeAgents.Count; } }

    /// <summary>
    /// 工作中任务代理数量
    /// </summary>
    public int WorkingAgentCount { get { return m_WorkingAgents.Count; } }

    /// <summary>
    /// 任务代理总数量
    /// </summary>
    public int TotalAgentCount
    {
        get
        {
            return FreeAgentCount + WorkingAgentCount;
        }
    }

    /// <summary>
    /// 等待中任务数量
    /// </summary>
    public int WaitingTaskCount { get { return m_WaitingTasks.Count; } }

    public TaskPool()
    {
        m_FreeAgents = new Stack<ITaskAgent<T>>();
        m_WorkingAgents = new LinkedList<ITaskAgent<T>>();
        m_WaitingTasks = new LinkedList<T>();
    }

然后添加任务代理的增加方法

    /// <summary>
    /// 增加任务代理
    /// </summary>
    /// <param name="agent">要增加的任务代理</param>
    public void AddAgent(ITaskAgent<T> agent)
    {
        if (agent == null)
        {
            Debug.LogError("要增加的任务代理为空");
        }

        agent.Initialize();
        m_FreeAgents.Push(agent);
    }

添加任务的增加与移除的方法

    /// <summary>
    /// 增加任务
    /// </summary>
    /// <param name="task">要增加的任务</param>
    public void AddTask(T task)
    {
        m_WaitingTasks.AddLast(task);
    }

    /// <summary>
    /// 移除任务
    /// </summary>
    /// <param name="serialId">要移除任务的序列编号</param>
    /// <returns>被移除的任务</returns>
    public T RemoveTask(int serialId)
    {
        foreach (T waitingTask in m_WaitingTasks)
        {
            if (waitingTask.SerialId == serialId)
            {
                m_WaitingTasks.Remove(waitingTask);
                return waitingTask;
            }
        }

        //连同工作中的任务代理一起移除
        foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
        {
            if (workingAgent.Task.SerialId == serialId)
            {
                workingAgent.Reset();
                m_FreeAgents.Push(workingAgent);
                m_WorkingAgents.Remove(workingAgent);
                return workingAgent.Task;
            }
        }

        return default(T);
    }

    /// <summary>
    /// 移除所有任务
    /// </summary>
    public void RemoveAllTasks()
    {
        m_WaitingTasks.Clear();
        //重置所有工作中任务代理
        foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
        {
            workingAgent.Reset();
            m_FreeAgents.Push(workingAgent);
        }
        m_WorkingAgents.Clear();
    }

最后添加任务池的轮询与关闭方法

    /// <summary>
    /// 任务池轮询
    /// </summary>
    public void Update(float elapseSeconds, float realElapseSeconds)
    {
        //获取第一个工作中任务代理
        LinkedListNode<ITaskAgent<T>> current = m_WorkingAgents.First;
        while (current != null)
        {
            //如果当前工作中任务代理已完成任务
            if (current.Value.Task.Done)
            {
                //就让它重置并从工作中任务代理中移除
                LinkedListNode<ITaskAgent<T>> next = current.Next;
                current.Value.Reset();
                m_FreeAgents.Push(current.Value);
                m_WorkingAgents.Remove(current);
                current = next;
                continue;
            }

            //未完成就轮询任务代理
            current.Value.Update(elapseSeconds, realElapseSeconds);
            current = current.Next;
        }

        //有可用任务代理并且有等待中任务
        while (FreeAgentCount > 0 && WaitingTaskCount > 0)
        {
            //出栈一个任务代理
            ITaskAgent<T> agent = m_FreeAgents.Pop();
            //添加到工作中任务代理
            LinkedListNode<ITaskAgent<T>> agentNode = m_WorkingAgents.AddLast(agent);

            //获取一个等待中的任务
            T task = m_WaitingTasks.First.Value;
            m_WaitingTasks.RemoveFirst();

            //开始处理这个任务
            agent.Start(task);
            if (task.Done)
            {
                agent.Reset();
                m_FreeAgents.Push(agent);
                m_WorkingAgents.Remove(agentNode);
            }
        }
    }


    /// <summary>
    /// 关闭并清理任务池
    /// </summary>
    public void Shutdown()
    {
        while (FreeAgentCount > 0)
        {
            m_FreeAgents.Pop().Shutdown();
        }

        foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
        {
            workingAgent.Shutdown();
        }
        m_WorkingAgents.Clear();

        m_WaitingTasks.Clear();
    }
现在对Task功能的编写已经基本完成了,我们将在下一篇编写DownLoad模块时对Task功能进行具体应用

猜你喜欢

转载自blog.csdn.net/qq_32821435/article/details/80558122