void InvokeStateChanged(StackChangeEvent <T> eventArg)
 {
     foreach (var subscription in m_Subscriptions)
     {
         subscription.ApplicationStateChanged(eventArg);
     }
 }
Beispiel #2
0
        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);
     }
 }
Beispiel #4
0
        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);
            });
        }
Beispiel #5
0
        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);
        }
Beispiel #7
0
 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);
        }
Beispiel #10
0
        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);
            });
        }