void RunStackAction(StackAction action, List <T> stack, Action onComplete) { if (stack.Count == 0) { ListPool <T> .Release(stack); onComplete.Invoke(); return; } var applicationState = stack.Last(); stack.RemoveAt(stack.Count - 1); var changeEvent = StackChangeEvent <T> .GetPooled(action, applicationState); var changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, changeEvent); changeStateRequest.OnComplete += () => { RunStackAction(action, stack, onComplete); StackChangeEvent <T> .Release(changeEvent); }; GetStateFromEnum(applicationState).ChangeState(changeEvent, changeStateRequest); }
public void Push(T applicationState, [NotNull] Action onComplete) { Assert.IsFalse(IsBusy); Assert.IsNotNull(onComplete); if (m_StatesStack.Count > 0 && m_StatesStack[0].Equals(applicationState)) { onComplete.Invoke(); return; } IsBusy = true; var oldStackState = ListPool <T> .Get(); oldStackState.AddRange(m_StatesStack); var newStackState = ListPool <T> .Get(); newStackState.AddRange(m_StatesStack); newStackState.Add(applicationState); var pausedSate = m_StatesStack.Last(); var stateWillChangeEvent = StackOperationEvent <T> .GetPooled(StackOperation.Push, applicationState, oldStackState, newStackState); Preprocess(stateWillChangeEvent, () => { InvokeStateWillChange(stateWillChangeEvent); var pauseEvent = StackChangeEvent <T> .GetPooled(StackAction.Paused, pausedSate); var addEvent = StackChangeEvent <T> .GetPooled(StackAction.Added, applicationState); var changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, pauseEvent); changeStateRequest.OnComplete += () => { changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, addEvent); changeStateRequest.OnComplete += () => { var stackSeComplete = StackOperationEvent <T> .GetPooled(StackOperation.Push, applicationState, oldStackState, newStackState); Postprocess(stackSeComplete, () => { IsBusy = false; m_StatesStack.Add(applicationState); InvokeStateChanged(stackSeComplete); ListPool <T> .Release(oldStackState); ListPool <T> .Release(newStackState); StackChangeEvent <T> .Release(addEvent); StackChangeEvent <T> .Release(pauseEvent); onComplete.Invoke(); }); }; GetStateFromEnum(applicationState).ChangeState(addEvent, changeStateRequest); }; GetStateFromEnum(pausedSate).ChangeState(pauseEvent, changeStateRequest); }); }
public void Set(T applicationState, [NotNull] Action onComplete) { Assert.IsFalse(IsBusy); Assert.IsNotNull(onComplete); if (m_StatesStack.Count == 1 && m_StatesStack[0].Equals(applicationState)) { onComplete.Invoke(); return; } IsBusy = true; var oldStackState = ListPool <T> .Get(); oldStackState.AddRange(m_StatesStack); var newStackState = ListPool <T> .Get(); newStackState.Add(applicationState); var stackSetOperationEvent = StackOperationEvent <T> .GetPooled(StackOperation.Set, applicationState, oldStackState, newStackState); Preprocess(stackSetOperationEvent, () => { InvokeStateWillChange(stackSetOperationEvent); RunStackAction(StackAction.Removed, oldStackState, () => { //oldStackState will be released so we need to make new one oldStackState = ListPool <T> .Get(); oldStackState.AddRange(m_StatesStack); var addEvent = StackChangeEvent <T> .GetPooled(StackAction.Added, applicationState); var changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, addEvent); changeStateRequest.OnComplete += () => { var stackSeComplete = StackOperationEvent <T> .GetPooled(StackOperation.Set, applicationState, oldStackState, newStackState); Postprocess(stackSeComplete, () => { IsBusy = false; m_StatesStack.Clear(); m_StatesStack.Add(applicationState); InvokeStateChanged(stackSeComplete); ListPool <T> .Release(oldStackState); ListPool <T> .Release(newStackState); StackChangeEvent <T> .Release(addEvent); onComplete.Invoke(); }); }; GetStateFromEnum(applicationState).ChangeState(addEvent, changeStateRequest); }); }); }
public void Pop([NotNull] Action onComplete) { Assert.IsFalse(IsBusy); Assert.IsNotNull(onComplete); if (m_StatesStack.Count == 0) { throw new Exception("States are empty"); } IsBusy = true; var oldStackState = ListPool <T> .Get(); oldStackState.AddRange(m_StatesStack); var removedSate = m_StatesStack.Last(); var newStackState = ListPool <T> .Get(); newStackState.AddRange(m_StatesStack); newStackState.Remove(removedSate); var resumedSate = newStackState.Last(); var stateWillChangeEvent = StackOperationEvent <T> .GetPooled(StackOperation.Pop, removedSate, oldStackState, newStackState); Preprocess(stateWillChangeEvent, () => { InvokeStateWillChange(stateWillChangeEvent); var removedEvent = StackChangeEvent <T> .GetPooled(StackAction.Removed, removedSate); var resumedEvent = StackChangeEvent <T> .GetPooled(StackAction.Resumed, resumedSate); var changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, removedEvent); changeStateRequest.OnComplete += () => { changeStateRequest = new ProgressListenerRequest(); changeStateRequest.OnProgressChange += () => InvokeProgressChange(changeStateRequest.Progress, resumedEvent); changeStateRequest.OnComplete += () => { var stackPopComplete = StackOperationEvent <T> .GetPooled(StackOperation.Pop, removedSate, oldStackState, newStackState); Postprocess(stackPopComplete, () => { IsBusy = false; m_StatesStack.Remove(removedSate); InvokeStateChanged(stackPopComplete); ListPool <T> .Release(oldStackState); ListPool <T> .Release(newStackState); StackChangeEvent <T> .Release(removedEvent); StackChangeEvent <T> .Release(resumedEvent); onComplete.Invoke(); }); }; GetStateFromEnum(resumedSate).ChangeState(resumedEvent, changeStateRequest); }; GetStateFromEnum(removedSate).ChangeState(removedEvent, changeStateRequest); }); }