Пример #1
0
        /// <summary>
        /// 요소를 스택에 추가
        /// </summary>
        /// <param name="item">추가할 요소</param>
        public virtual void Push(T item)
        {
            if (IsDebugEnabled)
            {
                log.Debug("Stack에 요소를 추가합니다. item=[{0}]", item);
            }

            lock (_syncLock) {
                InnerStack.Push(item);
                Monitor.Pulse(_syncLock);
            }
        }
Пример #2
0
        private T FindFirstOfType <T>() where T : InnerStack <TViewModel>
        {
            for (int index = _innerStacks.Count - 1; index >= 0; index--)
            {
                InnerStack <TViewModel> stack = _innerStacks[index];
                if (stack is T result)
                {
                    return(result);
                }
            }

            return(null);
        }
        private static UIViewController AsViewController(InnerStack item)
        {
            switch (item)
            {
            case SimpleControllerInnerStack simpleControllerInnerStack:
                return(simpleControllerInnerStack.Controller);

            case ModalControllerInnerStack modalControllerInnerStack:
                return(AsViewController(modalControllerInnerStack.Modal));

            default:
                throw new NotSupportedException($"Unsupported type of {item.GetType().Name}");
            }
        }
Пример #4
0
        /// <summary>
        /// 스택에서 요소를 꺼냄, 꺼낼 요소가 없으면 기다립니다.
        /// </summary>
        /// <returns>요소</returns>
        public virtual T Pop()
        {
            if (IsDebugEnabled)
            {
                log.Debug("Stack에서 요소를 꺼냅니다. 꺼낼 요소가 없으면 기다립니다...");
            }

            lock (_syncLock) {
                while (InnerStack.Count == 0)
                {
                    Monitor.Wait(_syncLock);
                }

                return(InnerStack.Pop());
            }
        }
Пример #5
0
        /// <summary>
        /// Stack에서 최상위 요소를 조회합니다. Stack이 비었으면 default(T)를 반환합니다.
        /// </summary>
        /// <returns>요소</returns>
        public virtual T Peek()
        {
            if (IsDebugEnabled)
            {
                log.Debug("Stack에서 최상위 요소를 조회합니다. Stack이 비었으면 기다리지 않고, default(T)를 반환합니다.");
            }

            lock (_syncLock) {
                if (InnerStack.Count == 0)
                {
                    return(default(T));
                }

                return(InnerStack.Peek());
            }
        }
Пример #6
0
        /// <summary>
        /// 스텍에서 요소를 꺼내본다. 꺼낼 요소가 없으면 False를 반환하고, item 은 default(T)가 설정된다.
        /// </summary>
        /// <param name="item">꺼낼 요소</param>
        /// <returns>꺼낼 요소가 없으면 False를 반환하고, item 은 default(T)가 설정된다.</returns>
        public virtual bool TryPop(out T item)
        {
            if (IsDebugEnabled)
            {
                log.Debug("스텍에서 요소를 꺼내본다. 꺼낼 요소가 없으면 기다리지 않고, False를 반환하고, item 은 default(T)가 설정된다.");
            }

            lock (_syncLock) {
                if (InnerStack.Count > 0)
                {
                    item = InnerStack.Pop();
                    return(true);
                }

                item = default(T);
                return(false);
            }
        }
Пример #7
0
        private List <PushOperation> Push(List <PushInformation <TViewModel> > pushInformations)
        {
            List <PushOperation>    pushOperations = new List <PushOperation>();
            InnerStack <TViewModel> top            = null;

            if (_innerStacks.Count > 0)
            {
                top = _innerStacks[_innerStacks.Count - 1];
            }

            foreach (var pushInformation in pushInformations)
            {
                if (pushInformation.Factory is ActivityViewFactory activityViewFactory)
                {
                    var activityInnerStack = new ActivityInnerStack <TViewModel>(this, activityViewFactory.ActivityType, activityIsOnlyAFragmentContainer: false, shouldClearHistory: activityViewFactory.ShouldClearHistory);
                    pushOperations.Add(new ActivityPushOperation <TViewModel>(activityInnerStack, pushInformation.Instance.ViewModelInstance));
                    top = activityInnerStack;
                    _innerStacks.Add(top);
                }
                else if (pushInformation.Factory is DialogFragmentViewFactory dialogFragmentViewFactory)
                {
                    var host = top.GetActivityInnerStack();
                    if (host == null)
                    {
                        //need to push the activity first
                        var activityInnerStack = new ActivityInnerStack <TViewModel>(this, dialogFragmentViewFactory.HostActivityType, activityIsOnlyAFragmentContainer: true, shouldClearHistory: dialogFragmentViewFactory.ShouldClearHistory);
                        pushOperations.Add(new ActivityPushOperation <TViewModel>(activityInnerStack, viewModel: null));
                        top = host = activityInnerStack;
                        _innerStacks.Add(top);
                    }

                    var fragment = dialogFragmentViewFactory.Creator();

                    //we set screeninformation to the fragment can retrieve its viewmodel
                    if (fragment is IScreenView screenView)
                    {
                        screenView.ScreenRoute = pushInformation.Instance.ToString();
                        _viewModelLocatorService.AddViewModel(pushInformation.Instance.ToString(), pushInformation.Instance.ViewModelInstance);
                    }

                    var dialogFragmentInnerStack = new DialogFragmentInnerStack <TViewModel>(this, host, fragment);
                    pushOperations.Add(new FragmentPushOperation <TViewModel>(host)
                    {
                        FragmentStacksToPush =
                        {
                            dialogFragmentInnerStack
                        }
                    });
                    top = dialogFragmentInnerStack;
                    _innerStacks.Add(top);
                }
                else if (pushInformation.Factory is FragmentViewFactory fragmentViewFactory)
                {
                    var activityHost = top.GetActivityInnerStack();
                    if (activityHost == null)
                    {
                        //need to push the activity first
                        var activityInnerStack = new ActivityInnerStack <TViewModel>(this, fragmentViewFactory.HostActivityType, activityIsOnlyAFragmentContainer: true, shouldClearHistory: fragmentViewFactory.ShouldClearHistory);
                        pushOperations.Add(new ActivityPushOperation <TViewModel>(activityInnerStack, viewModel: null));
                        top = activityHost = activityInnerStack;
                        _innerStacks.Add(top);
                    }

                    var fragment = fragmentViewFactory.Creator();

                    //we set screeninformation to the fragment can retrieve its viewmodel
                    if (fragment is IScreenView screenView)
                    {
                        screenView.ScreenRoute = pushInformation.Instance.ToString();
                        _viewModelLocatorService.AddViewModel(pushInformation.Instance.ToString(), pushInformation.Instance.ViewModelInstance);
                    }

                    var fragmentInnerStack = new FragmentInnerStack <TViewModel>(this, activityHost, fragment);
                    pushOperations.Add(new FragmentPushOperation <TViewModel>(activityHost)
                    {
                        FragmentStacksToPush =
                        {
                            fragmentInnerStack
                        }
                    });
                    activityHost.FragmentStack.Add(fragmentInnerStack);
                }
                else
                {
                    throw new InvalidOperationException("This kind of factory is not supported...");
                }
            }

            //simplify list of pop operations
            int insertIndex = 0;

            for (int i = 1; i < pushOperations.Count; i++)
            {
                if (TryMerge(pushOperations[insertIndex], pushOperations[i], out PushOperation op))
                {
                    pushOperations[insertIndex] = op;
                }
                else
                {
                    insertIndex++;
                    if (insertIndex != i)
                    {
                        pushOperations[insertIndex] = pushOperations[i];
                    }
                }
            }

            if (insertIndex < pushOperations.Count - 1)
            {
                int firstIndexToRemove = insertIndex + 1;
                pushOperations.RemoveRange(firstIndexToRemove, pushOperations.Count - firstIndexToRemove);
            }

            return(pushOperations);
        }