using Convention.Experimental.PublicType; using System; using System.Collections.Generic; namespace Convention.Experimental { public static class Architecture { private static readonly LinkedCacheList s_GameFrameworkModules = new(); /// /// 创建 /// /// 要创建的类型 /// 要创建的 private static GameModule CreateModule(Type moduleType, int stackLayer = 0) { if (stackLayer >= 100) { throw new GameException($"Create module '{moduleType.FullName}' failed, recursion too deep, there may be a circular dependency."); } GameModule module = (GameModule)Activator.CreateInstance(moduleType); if (module == null) { throw new GameException($"Can not create module '{moduleType.FullName}'"); } // 递归创建依赖模块 foreach (var dependenceType in module.Dependences()) _ = GetModule(dependenceType, stackLayer + 1); LinkedListNode current = s_GameFrameworkModules.First; while (current != null) { if (module.Priority > current.Value.Priority) { break; } current = current.Next; } if (current != null) { s_GameFrameworkModules.AddBefore(current, module); } else { s_GameFrameworkModules.AddLast(module); } return module; } /// /// 获取 /// /// 要获取的 /// 要获取的 /// 如果要获取的不存在,则自动创建该实例。 private static GameModule GetModule(Type moduleType, int stackLayer = 0) { foreach (GameModule module in s_GameFrameworkModules) { if (module.GetType() == moduleType) { return module; } } return CreateModule(moduleType, stackLayer + 1); } /// /// 获取游戏框架模块。 /// /// 要获取的游戏框架模块类型。 /// 要获取的游戏框架模块。 /// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。 public static T GetModule() where T : GameModule { return (T)GetModule(typeof(T)); } /// /// 关闭并清理所有游戏框架模块。 /// public static void Shutdown() { for (var current = s_GameFrameworkModules.Last; current != null; current = current.Previous) { current.Value.Shutdown(); } s_GameFrameworkModules.Clear(); ReferencePool.ClearAll(); Utility.Marshal.FreeCachedHGlobal(); } /// /// 所有游戏框架模块轮询。 /// /// 逻辑流逝时间,以秒为单位。 /// 真实流逝时间,以秒为单位。 public static void Update(float elapseSeconds, float realElapseSeconds) { foreach (var module in s_GameFrameworkModules) { module.Update(elapseSeconds, realElapseSeconds); } } } }