一、任务管理器模块设计
任务管理器的设计,类似于Handler类,为了同步或者异步加载时调用任务处理函数,是对执行某项任务(加载任务/下载任务/游戏内任务)在更新流程,完成流程,停止流程的一层封装,使用了状态模式。
1.任务执行者 TaskRoutine
顾名思义,执行者当然就是最苦的最累的类(Class),里面封装了大量的处理具体事务的函数。这个可以看作是一个数据结构,但是class又有是引用类型的特性,所以设计成了全公开的class。在UML类图中画出了类静态结构关系(成员变量和成员函数的结构)。
2.任务执行组 TaskGroup
有时一个任务可能包含多个子任务,而且这些子任务都执行完,这个任务才可以算是执行完成。例如加载assetbundle中的依赖资源,当把所有依赖assetbundle和主assetbundle都加载完成后,整个任务组才算是完成。所以为了执行类似这样的任务,我们设计了任务组TaskGroup。
3.任务管理器
管理者主要负责执行者的创建,任务组的创建,整体更新,记录的作用,用到了工厂模式,管理器整体结构较简单。
二、代码设计
1.任务执行者 TaskRoutine 代码
//任务执行器
public class TaskRoutine
{
//任务编号
public int TaskRoutineId;
//具体的任务(执行当前任务的时候,会一直回调这个函数)
public BaseAction CurrTask;
//任务完成(任务完成的时候,会执行这个回调)
public BaseAction OnComplete;
//停止任务(停止任务的时候,会执行这个回调)
public BaseAction StopTask;
//是否完成
public bool Complete {
get; private set; }
//任务数据
public object TaskData;
//离开任务
public void Leave()
{
Complete = true;
}
//进入任务
public void Enter()
{
Complete = false;
if (CurrTask != null)
{
CurrTask();
}
else
{
Leave();
}
}
public void OnUpdate()
{
if (Complete)
{
OnComplete?.Invoke();
CurrTask = null;
OnComplete = null;
Complete = false;
GameEntry.Pool.EnqueueClassObject(this);
}
}
}
2.任务执行组 TaskGroup 代码
//任务组
public class TaskGroup:IDisposable
{
//任务链表
LinkedList<TaskRoutine> m_ListTaskRoutine;
//任务组完成
public BaseAction OnComplete;
//是否并发执行
private bool m_IsConcurrency = false;
//任务总数量
private int m_TotalCount = 0;
//当前完成数量
private int m_CurrCount = 0;
public TaskGroup()
{
m_ListTaskRoutine = new LinkedList<TaskRoutine>();
}
public void AddTask(TaskRoutine routine)
{
m_ListTaskRoutine.AddLast(routine);
}
//检查并发任务是否完成
private void CheckConcurrencyTaskComplete()
{
m_CurrCount++;
if (m_CurrCount == m_TotalCount)
{
OnComplete?.Invoke();
Dispose();
GameEntry.Task.RemoveTaskGroup(this);
GameEntry.Pool.EnqueueClassObject(this);
}
}
//并发执行任务
private void ConCurrencyTask()
{
m_TotalCount = m_ListTaskRoutine.Count;
m_CurrCount = 0;
LinkedListNode<TaskRoutine> iter = m_ListTaskRoutine.First;
for (; iter != null;)
{
//保存next指针
LinkedListNode<TaskRoutine> next = iter.Next;
//进入
iter.Value.Enter();
//注册OnComplete,检查并发任务是否完成
iter.Value.OnComplete= () => {
CheckConcurrencyTaskComplete(); };
iter = next;
}
}
//检查任务
private void CheckTask()
{
LinkedListNode<TaskRoutine> iter = m_ListTaskRoutine.First;
if (iter != null)
{
iter.Value.OnComplete = () =>
{
//链表中移除
m_ListTaskRoutine.Remove(iter);
//递归检查
CheckTask();
};
}
else
{
OnComplete?.Invoke();
Dispose();
GameEntry.Task.RemoveTaskGroup(this);
GameEntry.Pool.EnqueueClassObject(this);
}
}
//跑路函数Run
public void Run(bool isConcurrency = false)
{
m_IsConcurrency = isConcurrency;
if (m_IsConcurrency)
{
ConCurrencyTask();
}
else
{
CheckTask();
}
}
//更新所有
public void OnUpdate()
{
LinkedListNode<TaskRoutine> iter = m_ListTaskRoutine.First;
for (; iter != null;)
{
iter.Value.OnUpdate();
iter = iter.Next;
}
}
//清空所有
public void RemoveAllTask()
{
LinkedListNode<TaskRoutine> iter = m_ListTaskRoutine.First;
//TaskRoutine routine = null;
for (; iter != null;)
{
LinkedListNode<TaskRoutine> next= iter.Next;
//执行一下StopTask
iter.Value.StopTask?.Invoke();
//把对象放到池子里
GameEntry.Pool.EnqueueClassObject(iter);
//移除
m_ListTaskRoutine.Remove(iter);
//next
iter = next;
}
}
public void Dispose()
{
m_ListTaskRoutine.Clear();
OnComplete = null;
//throw new NotImplementedException();
}
}
3.3.任务管理器 代码
//任务管理器
public class TaskManager : ManagerBase, IDisposable
{
//任务组链表
private LinkedList<TaskGroup> m_ListTaskGroup;
public TaskManager()
{
m_ListTaskGroup = new LinkedList<TaskGroup>();
}
public override void Init()
{
}
//创建任务执行器
public TaskRoutine CreateTaskRoutine()
{
return GameEntry.Pool.DequeueClassObject<TaskRoutine>();
}
//创建任务执行器组(简称:任务组)
public TaskGroup CreateTaskGroup()
{
return GameEntry.Pool.DequeueClassObject<TaskGroup>();
}
//移除任务组
public void RemoveTaskGroup(TaskGroup taskGroup)
{
m_ListTaskGroup.Remove(taskGroup);
}
//更新
public void OnUpdate()
{
LinkedListNode<TaskGroup> iter = m_ListTaskGroup.First;
for (; iter != null;)
{
iter.Value.OnUpdate();
iter = iter.Next;
}
}
public void Dispose()
{
}
}