using System; using System.Collections.Generic; namespace AibisDream.Kit { public interface IParallel : ISequence { } internal class Parallel : IParallel { private Parallel() { } private static readonly SimpleObjectPool SimpleObjectPool = new(() => new Parallel(), null, 5); private readonly List _actions = ListPool.Get(); private int _finishedCount; public static Parallel Allocate() { var parallel = SimpleObjectPool.Allocate(); parallel.ActionID = ActionKit.IDGenerator++; parallel.IsFinalized = false; parallel.Reset(); return parallel; } public bool Paused { get; set; } public bool IsFinalized { get; set; } public ulong ActionID { get; set; } public ActionStatus Status { get; set; } public void OnStart() { } public void OnExecute(float dt) { for (var i = _finishedCount; i < _actions.Count; i++) { if (!_actions[i].Execute(dt)) continue; _finishedCount++; if (_finishedCount >= _actions.Count) { this.Finish(); } else { // swap (_actions[i], _actions[_finishedCount - 1]) = (_actions[_finishedCount - 1], _actions[i]); } } } public void OnFinish() { } public ISequence Append(IAction action) { _actions.Add(action); return this; } public void Deinit() { if (!IsFinalized) { IsFinalized = true; foreach (var action in _actions) { action.Deinit(); } _actions.Clear(); ActionKitMonoBehaviourEvents.AddCallback( new ActionQueueRecycleCallback(SimpleObjectPool, this)); } } public void Reset() { Status = ActionStatus.NotStart; _finishedCount = 0; Paused = false; foreach (var action in _actions) { action.Reset(); } } } public static class ParallelExtension { public static ISequence Parallel(this ISequence self, Action parallelSetting) { var parallel = Kit.Parallel.Allocate(); parallelSetting(parallel); return self.Append(parallel); } } }