using System; using System.Collections.Generic; using System.Linq; using Convention; using UnityEngine; namespace Demo.Game { /// /// 全局扁平化Update调度器 /// public class UpdateScheduler { // 永久活跃对象 private readonly List permanentObjects = new(); // 时间范围对象(排序队列) private readonly SortedDictionary> activationQueue = new(); private readonly SortedDictionary> deactivationQueue = new(); // 当前活跃对象 private readonly List activeObjects = new(); // 统计信息 public int TotalRegistered => permanentObjects.Count + activationQueue.Values.Sum(l => l.Count); public int CurrentActive => permanentObjects.Count + activeObjects.Count; /// /// 注册对象到调度器 /// public void Register(IUpdateable obj, UpdateMode mode, float startTime = 0f, float endTime = float.MaxValue) { if (obj == null) { Debug.LogError("[UpdateScheduler] 尝试注册null对象"); return; } switch (mode) { case UpdateMode.Permanent: if (!permanentObjects.Contains(obj)) { permanentObjects.Add(obj); Debug.Log($"[UpdateScheduler] 注册永久对象: {obj.GetUpdateName()}"); } break; case UpdateMode.TimeBound: // 注册激活时间 if (!activationQueue.ContainsKey(startTime)) activationQueue[startTime] = new List(); if (!activationQueue[startTime].Contains(obj)) { activationQueue[startTime].Add(obj); Debug.Log($"[UpdateScheduler] 注册时间范围对象: {obj.GetUpdateName()} ({startTime:F2}s - {endTime:F2}s)"); } // 注册停用时间 if (!deactivationQueue.ContainsKey(endTime)) deactivationQueue[endTime] = new List(); if (!deactivationQueue[endTime].Contains(obj)) { deactivationQueue[endTime].Add(obj); } break; case UpdateMode.Manual: // 手动模式不自动注册 Debug.Log($"[UpdateScheduler] 手动模式对象: {obj.GetUpdateName()}"); break; } } /// /// 手动激活对象(Manual模式) /// public void Activate(IUpdateable obj) { if (!activeObjects.Contains(obj)) { activeObjects.Add(obj); } } /// /// 手动停用对象(Manual模式) /// public void Deactivate(IUpdateable obj) { activeObjects.Remove(obj); } /// /// 主Update循环 - 扁平化遍历 /// public void DoUpdate(float currentTime, float deltaTime, ScriptableObject.TickType tickType) { // 时间分片管理 using (Profiler.BeginZone("UpdateScheduler.TimeSlicing")) { ProcessActivations(currentTime); ProcessDeactivations(currentTime); } // 扁平更新所有活跃对象 using (Profiler.BeginZone($"UpdateScheduler.FlatUpdate (Permanent:{permanentObjects.Count} Active:{activeObjects.Count})")) { // 永久活跃对象 for (int i = 0; i < permanentObjects.Count; i++) { if (permanentObjects[i]?.IsUpdateReady == true) { permanentObjects[i].DoUpdate(currentTime, deltaTime, tickType); } } // 当前活跃对象 for (int i = activeObjects.Count - 1; i >= 0; i--) { if (activeObjects[i] == null || !activeObjects[i].IsUpdateReady) { activeObjects.RemoveAt(i); continue; } activeObjects[i].DoUpdate(currentTime, deltaTime, tickType); } } } private void ProcessActivations(float currentTime) { while (activationQueue.Count > 0) { var firstKey = activationQueue.Keys.First(); if (firstKey > currentTime) break; var objects = activationQueue[firstKey]; foreach (var obj in objects) { if (obj != null && !activeObjects.Contains(obj)) { activeObjects.Add(obj); Debug.Log($"[UpdateScheduler] 激活: {obj.GetUpdateName()} @ {currentTime:F2}s"); } } activationQueue.Remove(firstKey); } } private void ProcessDeactivations(float currentTime) { while (deactivationQueue.Count > 0) { var firstKey = deactivationQueue.Keys.First(); if (firstKey > currentTime) break; var objects = deactivationQueue[firstKey]; foreach (var obj in objects) { activeObjects.Remove(obj); if (obj != null) { Debug.Log($"[UpdateScheduler] 停用: {obj.GetUpdateName()} @ {currentTime:F2}s"); } } deactivationQueue.Remove(firstKey); } } /// /// 重置调度器(用于Reset/Restart) /// public void Reset() { activeObjects.Clear(); Debug.Log("[UpdateScheduler] 重置完成"); } /// /// 清空所有注册 /// public void Clear() { permanentObjects.Clear(); activationQueue.Clear(); deactivationQueue.Clear(); activeObjects.Clear(); Debug.Log("[UpdateScheduler] 清空所有注册"); } } }