using System; using System.Collections.Generic; namespace ET { public static class Game { [StaticField] private static readonly Dictionary singletonTypes = new Dictionary(); [StaticField] private static readonly Stack singletons = new Stack(); [StaticField] private static readonly Queue updates = new Queue(); [StaticField] private static readonly Queue lateUpdates = new Queue(); [StaticField] private static readonly Queue frameFinishTask = new Queue(); public static T AddSingleton() where T: Singleton, new() { T singleton = new T(); AddSingleton(singleton); return singleton; } public static void AddSingleton(ISingleton singleton) { Type singletonType = singleton.GetType(); if (singletonTypes.ContainsKey(singletonType)) { throw new Exception($"already exist singleton: {singletonType.Name}"); } singletonTypes.Add(singletonType, singleton); singletons.Push(singleton); singleton.Register(); if (singleton is ISingletonAwake awake) { awake.Awake(); } if (singleton is ISingletonUpdate) { updates.Enqueue(singleton); } if (singleton is ISingletonLateUpdate) { lateUpdates.Enqueue(singleton); } } public static async ETTask WaitFrameFinish() { ETTask task = ETTask.Create(true); frameFinishTask.Enqueue(task); await task; } public static void Update(int timeMS) { int count = updates.Count; while (count-- > 0) { ISingleton singleton = updates.Dequeue(); if (singleton.IsDisposed()) { continue; } if (singleton is not ISingletonUpdate update) { continue; } updates.Enqueue(singleton); try { update.Update(timeMS); } catch (Exception e) { Log.Error(e); } } } public static void LateUpdate() { int count = lateUpdates.Count; while (count-- > 0) { ISingleton singleton = lateUpdates.Dequeue(); if (singleton.IsDisposed()) { continue; } if (singleton is not ISingletonLateUpdate lateUpdate) { continue; } lateUpdates.Enqueue(singleton); try { lateUpdate.LateUpdate(); } catch (Exception e) { Log.Error(e); } } } public static void FrameFinishUpdate() { while (frameFinishTask.Count > 0) { ETTask task = frameFinishTask.Dequeue(); task.SetResult(); } } public static void Close() { // 顺序反过来清理 while (singletons.Count > 0) { ISingleton iSingleton = singletons.Pop(); iSingleton.Destroy(); } singletonTypes.Clear(); } } }