模块基类
因为我们不使用单例来作为模块的唯一性,使用全局管理得模块入口来管理模块。
模块特点 :
1.和单例一样,使用该模块得时候才会被创建,且具有唯一性。
2.模块之间存在优先级,优先级高的,优先轮序。Priority该值越小 优先级越高
public abstract class BubbleFrameModel
{
/// <summary>
/// 优先级 根据这个值来 优先轮序
/// </summary>
internal virtual int Priority => 0;
/// <summary>
/// update 更新
/// </summary>
/// <param name="dt"></param>
internal virtual void DoUpdate(float dt)
{
}
}
模块管理入口((类名)BubbleFrameEntry)
在管理类里,由于我们存在模块之间得优先级,在创建模块时,需要对模块进行一个排序,在获取模块时,需要对模块进行一个优先级由高到低的顺序遍历。
所以我们用链表来储存模块。链表的做法可以参考网上,有很多教程。使用链表的优势有很多,首当其冲的就是插入和删除便捷,其次就是开始无需給定长度,长度可动态增长和减少。也非常适用于我们的优先级从高到低的顺序查找。
获取对应模块 (方法名(GetModel))
/// <summary>
/// 获取模块
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetModel<T>() where T : BubbleFrameModel
{
Type type = typeof(T);
if (type.IsAbstract)
{
throw new GameException($"{type} is invalid");
}
foreach (var model in GameModels)
{
if (model.GetType()==type)
{
return model as T;
}
}
return CreateModel(type) as T;
}
当外部需要使用该模块的功能时,需要在模块入口内获取该模块,如果该类型时抽象类,说明调用类不对,否则就遍历该模块链表返回对应的模块。
创建对应模块 (方法名(CreateModelByType))
如果链表内不存在该模块,需要创建该模块。
public BubbleFrameModel CreateModelByType(Type type)
{
BubbleFrameModel instance = (BubbleFrameModel) Activator.CreateInstance(type);
LinkedListNode<BubbleFrameModel> current = GameModels.First;
LinkedListNode<BubbleFrameModel> beforeNode = null;
while (current!=null)
{
if (current.Value.Priority > instance.Priority)
{
beforeNode = current;
break;
}
current = current.Next;
}
if (beforeNode!=null)
{
GameModels.AddBefore(beforeNode, instance);
}
else
{
GameModels.AddLast(instance);
}
Idle = true;
return instance;
}
}
代码很简单,当模块链表里不存在这个这个模块的实例对象,说明是首次使用该模块,这个时候需要把模块动态创建 ,使用反射创建该类型的实例,接着就是正常的遍历模块链表,判断下一个节点的Priority是否大于当前模块的Priority,大于则插入,不存在这类节点就插入链表的尾节点。
调整:
这样可能会延伸出一个问题,当俩个进程重复调用静态方法时,静态方法只会执行一次,所以在这创建一个创建模块的进程类,当这个进程类中正在创建模块时,我们重新创建一个构建模块类。
当存在空闲状态的进程类时,则使用这个进程类创建对象,如果没有该进程类,则创建一个空闲状态的进程类,创建模块对象。
构建模块类时,使用反射创建模块对象,插入到优先级队列中,将自己的构建模块类的状态变成空闲状态,便于下个模块类调用。
这样就完成了模块的入口,没有使用单例模式,使用反射机制创建需要的各模块对象。