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 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); }