GameFramework任务池TaskPool
类图
任务执行可扩展
使用
// 定义你的任务的数据结构
class YourTask : TaskBase
{
public string url;
}
// 定义你的任务执行器
class YourTaskAgent : ITaskAgent<YourTask>
{
public void Initialize()
{
// 初始化,只会调用一次
}
public void Shutdown()
{
// 关闭,只会调用一次
}
public void Update(float elapseSeconds, float realElapseSeconds)
{
// 检查超时
}
public StartTaskStatus Start(WebRequestTask task)
{
// 开始任务
}
public void Reset()
{
// 停止并重置,然后可以开始下一个任务
}
}
// 使用任务池
class TestTaskPool
{
void Start()
{
// 创建任务池
m_TaskPool = new TaskPool<YourTask>();
// 添加执行器
for (int i=0; i<10; i++)
{
m_TaskPool.AddAgent(new YourTaskAgent());
}
}
public int RunTask(string url)
{
// 创建任务并添加到任务池
YourTask task = new YourTask(url);
m_TaskPool.AddTask(task);
return task.SerialId;
}
void OnDestroy()
{
m_TaskPool.Shutdown();
}
}
为什么我们的 YourTaskAgent 跟 GameFramework 内置的几个 TaskAgent 长得不一样
因为那几个 TaskAgent 又封装了一层,把功能分给了 AgentHelper,可以扩展不同的实现
实现如下
// 定义功能扩展点
interface IYourTaskAgentHelper
{
void DoSomething(string url);
}
// 定义一个具体实现
class DefaultYourTaskAgentHelper : IYourTaskAgentHelper
{
public void DoSomething(string url)
{
// 做具体的任务,比如下载东西
}
}
// 然后上面的 YourTaskAgent 替换成下面这样
class YourTaskAgent : ITaskAgent<YourTask>
{
IYourTaskAgentHelper m_helper;
public YourTaskAgent(IYourTaskAgentHelper helper)
{
m_helper = helper;
}
public void Initialize()
{
// 初始化,只会调用一次
}
public void Shutdown()
{
// 关闭,只会调用一次
}
public void Update(float elapseSeconds, float realElapseSeconds)
{
// 检查超时
}
public StartTaskStatus Start(WebRequestTask task)
{
// 开始任务
m_helper.DoSomething(task.url);
}
public void Reset()
{
// 停止并重置,然后可以开始下一个任务
m_helper.Reset();
}
}
// 上面的 TestTaskPool 初始化替换成这样
class TestTaskPool
{
void Start()
{
// 创建任务池
m_TaskPool = new TaskPool<YourTask>();
// 添加执行器
for (int i=0; i<10; i++)
{
m_TaskPool.AddAgent(new YourTaskAgent(new DefaultYourTaskAgentHelper()));
}
}
}
代码分析
// 添加任务
TaskPool<YourTask>.AddTask(YourTask task)
{
m_WaitingTasks.AddAfter(current, task); // 任务加入等待队列
}
// 执行任务
TaskPool<YourTask>.Update(elapseSeconds, realElapseSeconds)
{
ProcessRunningTasks(elapseSeconds, realElapseSeconds)
{
YourTaskAgent taskAgent = m_WorkingAgents.First;
taskAgent.Update(elapseSeconds, realElapseSeconds)
{
// 判断正在下载的任务是否超时
}
}
ProcessWaitingTasks(elapseSeconds, realElapseSeconds) // TaskPool<YourTask>.ProcessWaitingTasks
{
LinkedListNode<YourTask> current = m_WaitingTasks.First; // 从等待列表中取出第1个任务
YourTask task = current.Value;
YourTaskAgent agent = m_FreeAgents.Pop(); // 获得空闲下载任务执行器
LinkedListNode<YourTaskAgent> agentNode = m_WorkingAgents.AddLast(agent); // 加入执行器列表中
StartTaskStatus status = agent.Start(task); // 用执行器下载任务
}
}