Beispiel #1
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);
        }
Beispiel #2
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 #3
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);
                });
            });
        }
Beispiel #4
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);
            });
        }