void InvokeStateChanged(StackChangeEvent <T> eventArg) { foreach (var subscription in m_Subscriptions) { subscription.ApplicationStateChanged(eventArg); } }
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); }
void InvokeProgressChange(float p, StackChangeEvent <T> eventArg) { foreach (var subscription in m_Subscriptions) { subscription.ApplicationStateChangeProgressChanged(p, eventArg); } }
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); }); }); }
void InvokeChangeActionInStack(StackChangeEvent <T> stackChangeEvent, GroupRequest groupReq, int index = 0) { if (index >= m_StatesStack.Count) { groupReq.SetDone(); return; } var state = m_StatesStack[index]; index++; var request = new Request(); request.Done += () => InvokeChangeActionInStack(stackChangeEvent, groupReq, index); groupReq.AddRequest(request); m_EnumToState[state].ChangeState(stackChangeEvent, request); }
public static void Release(StackChangeEvent <TEnum> stackChangeEvent) { s_EventsPool.Release(stackChangeEvent); }
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; m_OldStackState = ListPool <T> .Get(); m_OldStackState.AddRange(m_StatesStack); m_NewStackState = ListPool <T> .Get(); m_NewStackState.Add(applicationState); var removedEvent = StackChangeEvent <T> .GetPooled(StackAction.Removed, m_OldStackState, m_NewStackState); var addEvent = StackChangeEvent <T> .GetPooled(StackAction.Added, m_OldStackState, m_NewStackState); var groupReq = new GroupRequest(2); groupReq.Done += onComplete.Invoke; var removeReq = new GroupRequest(m_OldStackState.Count); var addReq = new GroupRequest(m_NewStackState.Count); removeReq.ProgressChange += _ => InvokeProgressChange(groupReq.Progress, removedEvent); removeReq.Done += () => { InvokeStateChanged(removedEvent); StackChangeEvent <T> .Release(removedEvent); InvokeStateWillChange(addEvent); InvokeChangeActionInStack(addEvent, addReq); }; addReq.ProgressChange += _ => InvokeProgressChange(groupReq.Progress, addEvent); addReq.Done += () => { ListPool <T> .Release(m_OldStackState); ListPool <T> .Release(m_NewStackState); m_StatesStack.Clear(); m_StatesStack.Add(applicationState); InvokeStateChanged(addEvent); StackChangeEvent <T> .Release(addEvent); IsBusy = false; }; groupReq.AddRequest(removeReq); groupReq.AddRequest(addReq); InvokeStateWillChange(removedEvent); InvokeChangeActionInStack(removedEvent, removeReq); }
public void Pop([NotNull] Action <T> onComplete) { Assert.IsFalse(IsBusy); Assert.IsNotNull(onComplete); if (m_StatesStack.Count == 0) { throw new Exception("States are empty"); } IsBusy = true; m_OldStackState = ListPool <T> .Get(); m_OldStackState.AddRange(m_StatesStack); var applicationState = m_StatesStack.Last(); m_NewStackState = ListPool <T> .Get(); m_NewStackState.AddRange(m_StatesStack); m_NewStackState.Remove(applicationState); var removedEvent = StackChangeEvent <T> .GetPooled(StackAction.Removed, m_OldStackState, m_NewStackState); var resumedEvent = StackChangeEvent <T> .GetPooled(StackAction.Resumed, m_OldStackState, m_NewStackState); var group = new GroupRequest(2); group.Done += () => onComplete.Invoke(applicationState); var removeReq = new Request(); var resumeReq = new Request(); removeReq.ProgressChange += _ => InvokeProgressChange(group.Progress, removedEvent); removeReq.Done += () => { m_StatesStack.Remove(applicationState); InvokeStateChanged(removedEvent); StackChangeEvent <T> .Release(removedEvent); InvokeStateWillChange(resumedEvent); if (m_StatesStack.Count > 0) { m_EnumToState[m_StatesStack.Last()].ChangeState(resumedEvent, resumeReq); } else { resumeReq.SetDone(); } }; resumeReq.ProgressChange += _ => InvokeProgressChange(group.Progress, resumedEvent); resumeReq.Done += () => { ListPool <T> .Release(m_OldStackState); ListPool <T> .Release(m_NewStackState); InvokeStateChanged(resumedEvent); IsBusy = false; }; group.AddRequest(removeReq); group.AddRequest(resumeReq); InvokeStateWillChange(removedEvent); m_EnumToState[applicationState].ChangeState(removedEvent, removeReq); }
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); }); }