把看完代码的部分思路记录在博客上,某种程度上来说真是一件枯燥的事情,因为看代码的速度有时候很快记录下来却要花费很多时间。
但我的心态过于浮躁了,对事物的掌握很容易因为浮躁而失去应有的水准,希望能通过坚持更新GF系列笔记,打磨一下自己的浮躁心态。
对GF任务的理解
GF的任务模块本质上是对各种任务池子的维护与轮询更新,至于任务本身是什么,我们拥有广阔的自定义空间。
任务有个大体的结构:1.任务行为代理(agent),2.任务内容(task)
E神在自己的框架中定义和使用了三种任务(下面给出代理类名):
1.DownloadAgent,2.LoadResourceAgent,3.WebRequestAgent
继续阅读框架我们会逐渐遇见这三种任务类型。
伪代码展示
TaskPool
TaskPool管理和维护着一个系列的任务的轮询更新,体现了任务池基本的运作方式
通过对数据定义的观察,可以看出此任务池的实现对内存的使用控制非常小心谨慎
class TaskPool<T> where T : TaskBase
{
private readonly Stack<ITaskAgent<T>> m_FreeAgents;
private readonly GameFrameworkLinkedList<ITaskAgent<T>> m_WorkingAgents;
private readonly GameFrameworkLinkedList<T> m_WaitingTasks;
public bool Paused;/// 获取或设置任务池是否被暂停。
public int TotalAgentCount;/// 获取任务代理总数量。
public int FreeAgentCount;/// 获取可用任务代理数量。
public int WorkingAgentCount;/// 获取工作中任务代理数量。
public int WaitingTaskCount;/// 获取等待任务数量。
/// <summary>
/// 任务池轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
public void Update(float elapseSeconds, float realElapseSeconds)
{
if (m_Paused)
{
return;
}
//轮询处理运行中任务
ProcessRunningTasks(elapseSeconds, realElapseSeconds);
//处理刚加入轮询还在等待状态中的任务
ProcessWaitingTasks(elapseSeconds, realElapseSeconds);
}
}
ITaskAgent
任务代理可以说标识着任务的行为
剩下一些细节就不做过多的展示,基本流程应该已经体现出来了,TaskBase也是在引用池的管理之下
interface ITaskAgent<T> where T : TaskBase
{
/// <summary>
/// 获取任务。
/// </summary>
T Task
{
get;
}
/// <summary>
/// 初始化任务代理。
/// </summary>
void Initialize();
/// <summary>
/// 任务代理轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
void Update(float elapseSeconds, float realElapseSeconds);
/// <summary>
/// 关闭并清理任务代理。
/// </summary>
void Shutdown();
/// <summary>
/// 开始处理任务。
/// </summary>
/// <param name="task">要处理的任务。</param>
/// <returns>开始处理任务的状态。</returns>
StartTaskStatus Start(T task);
/// <summary>
/// 停止正在处理的任务并重置任务代理。
/// </summary>
void Reset();
}
使用实践
BuffTask 与 BuffAgent
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameFramework;
public class BuffTask :TaskBase
{
string bufTest;
public float T_Timeout;
public float F_Time;
public static BuffTask Create(string buf,int ftimeout,int ttimeout,object userData)
{
BuffTask buffTask = ReferencePool.Acquire<BuffTask>();
buffTask.Initialize(1,"",1, userData);
buffTask.bufTest = buf;
buffTask.F_Time = ftimeout;
buffTask.T_Timeout = ttimeout;
return buffTask;
}
/// <summary>
/// 清理buff任务。
/// </summary>
public override void Clear()
{
base.Clear();
bufTest = null;
}
}
public class BuffAgent: ITaskAgent<BuffTask>
{
private BuffTask m_Task;
public BuffTask Task
{
get
{
return m_Task;
}
}
public void Initialize()
{
Debug.LogError("Agent Initialize");
}
public void Reset()
{
m_Task.Clear();
}
public void Shutdown()
{
m_Task.Clear();
}
public StartTaskStatus Start(BuffTask task)
{
m_Task = task;
return StartTaskStatus.CanResume;
}
public void Update(float elapseSeconds, float realElapseSeconds)
{
//Debug.LogError("buf over");
m_Task.F_Time += realElapseSeconds;
if (m_Task.T_Timeout <= m_Task.F_Time)
{
Debug.LogError("buf over");
m_Task.Done = true;
}
}
}
runtime.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameFramework;
using UnityGameFramework.Runtime;
using System;
using GameFramework.Event;
namespace StarForce
{
public class TestNode : MonoBehaviour
{
TaskPool<BuffTask> taskPool;
private void Awake()
{
taskPool = new TaskPool<BuffTask>();
taskPool.AddAgent(new BuffAgent());
taskPool.AddTask(BuffTask.Create("11",0,2,null));
Debug.LogError($"FreeAgentCount{taskPool.FreeAgentCount}---TotalAgentCount{taskPool.TotalAgentCount}----WorkingAgentCount{taskPool.WorkingAgentCount}");
}
public void Update()
{
taskPool.Update(Time.deltaTime,Time.deltaTime);
if (Input.GetKeyDown(KeyCode.G))
{
Debug.LogError($"FreeAgentCount{taskPool.FreeAgentCount}---TotalAgentCount{taskPool.TotalAgentCount}----WorkingAgentCount{taskPool.WorkingAgentCount}");
}
}
}
}
Comments | NOTHING