using System.Collections.Generic; namespace Syntriax.Engine.Core; public class UpdateManager : UniverseObject { private static Comparer SortByDescendingPriority() => Comparer.Create((x, y) => y.Priority.CompareTo(x.Priority)); private readonly ActiveBehaviourCollectorSorted firstFrameUpdates = new() { SortBy = SortByDescendingPriority() }; private readonly ActiveBehaviourCollectorSorted preUpdateEntities = new() { SortBy = SortByDescendingPriority() }; private readonly ActiveBehaviourCollectorSorted updateEntities = new() { SortBy = SortByDescendingPriority() }; private readonly ActiveBehaviourCollectorSorted postUpdateEntities = new() { SortBy = SortByDescendingPriority() }; private readonly List toCallFirstFrameUpdates = new(32); protected override void OnEnteringUniverse(IUniverse universe) { firstFrameUpdates.Assign(universe); preUpdateEntities.Assign(universe); updateEntities.Assign(universe); postUpdateEntities.Assign(universe); universe.OnPreUpdate.AddListener(OnPreUpdate); universe.OnUpdate.AddListener(OnUpdate); universe.OnPostUpdate.AddListener(OnPostUpdate); } protected override void OnExitingUniverse(IUniverse universe) { firstFrameUpdates.Unassign(); preUpdateEntities.Unassign(); updateEntities.Unassign(); postUpdateEntities.Unassign(); universe.OnPreUpdate.RemoveListener(OnPreUpdate); universe.OnUpdate.RemoveListener(OnUpdate); universe.OnPostUpdate.RemoveListener(OnPostUpdate); } private void OnPreUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = toCallFirstFrameUpdates.Count - 1; i >= 0; i--) { toCallFirstFrameUpdates[i].FirstActiveFrame(); toCallFirstFrameUpdates.RemoveAt(i); } for (int i = preUpdateEntities.Count - 1; i >= 0; i--) preUpdateEntities[i].PreUpdate(); } private void OnUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = updateEntities.Count - 1; i >= 0; i--) updateEntities[i].Update(); } private void OnPostUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = postUpdateEntities.Count - 1; i >= 0; i--) postUpdateEntities[i].PostUpdate(); } private void OnFirstFrameCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) { toCallFirstFrameUpdates.Add(args.BehaviourCollected); } public UpdateManager() { firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected); } }