Пример #1
0
        public void Shouldnt_Count_Unique_Enqueue_For_Limit_In_Loop()
        {
            var target = new LayoutQueue <string>(_ => true);

            //1
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.BeginLoop(3);

            target.Dequeue();

            //2
            target.Enqueue("Foo");
            target.Enqueue("Foo");
            target.Dequeue();

            //3
            target.Enqueue("Foo");
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.Dequeue();

            //4 more than limit shouldn't be added
            target.Enqueue("Foo");

            Assert.Equal(0, target.Count);
        }
Пример #2
0
        public virtual ValueSize MeasureElement <TRenderSize>(IVisualElement element,
                                                              TRenderSize availableSpace)
            where TRenderSize : IRenderSize
        {
            if (!element.IsRequiresMeasure)
            {
                lock (_measureLock)
                {
                    if (_lastMeasurements.TryGetValue(element, out var val))
                    {
                        LayoutQueue.RemoveVisualFromMeasureQueue(element);
                        return(val);
                    }
                }
            }

            // measure anyways if we know nothing of it...?
            //return ValueSize.Empty;

            VisualLineage.PushVisual(element);
            //_styleContext.PushVisual(element);

            var layoutElement = GetElementForLayout(element);

            ////////////////////////
            var res = MeasureElementImpl(layoutElement, availableSpace);

            ////////////////////////

            LayoutQueue.RemoveVisualFromMeasureQueue(element);
            element.AcceptChanges(ChangeType.Measure);
            return(res);
        }
Пример #3
0
        public void Should_Enqueue_When_Condition_True_After_Loop_When_Limit_Met()
        {
            var target = new LayoutQueue <string>(_ => true);

            //1
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.BeginLoop(3);

            target.Dequeue();

            //2
            target.Enqueue("Foo");
            target.Dequeue();

            //3
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.Dequeue();

            //4 more than limit shouldn't be added to queue
            target.Enqueue("Foo");

            Assert.Equal(0, target.Count);

            target.EndLoop();

            //after loop should be added once
            Assert.Equal(1, target.Count);
            Assert.Equal("Foo", target.First());
        }
Пример #4
0
        public void Shouldnt_Enqueue_When_Condition_False_After_Loop_When_Limit_Met()
        {
            var target = new LayoutQueue <string>(_ => false);

            //1
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.BeginLoop(3);

            target.Dequeue();

            //2
            target.Enqueue("Foo");
            target.Dequeue();

            //3
            target.Enqueue("Foo");

            Assert.Equal(1, target.Count);

            target.Dequeue();

            //4 more than limit shouldn't be added
            target.Enqueue("Foo");

            Assert.Equal(0, target.Count);

            target.EndLoop();

            Assert.Equal(0, target.Count);
        }
        private void Init(IWindowManager windowManager,
                          IThemeProvider themeProvider,
                          IViewPerspective viewPerspective,
                          DisplayMetrics displayMetrics,
                          AndroidFontProvider fontProvider,
                          IViewState viewState,
                          IUiProvider uiProvider,
                          ref AndroidMeasureKit measureContext,
                          ref AndroidRenderContext renderContext,
                          ref RefreshRenderContext refreshRenderContext)
        {
            var imageProvider = new AndroidImageProvider(displayMetrics);

            var visualLineage = new VisualLineage();

            var lastMeasures = new Dictionary <IVisualElement, ValueSize>();

            var layoutQueue = new LayoutQueue();

            measureContext = new AndroidMeasureKit(windowManager, fontProvider,
                                                   this, lastMeasures, themeProvider, displayMetrics, visualLineage, layoutQueue);

            var visualPositions = new Dictionary <IVisualElement, ValueCube>();

            renderContext = new AndroidRenderContext(viewPerspective,
                                                     fontProvider, viewState, this, visualPositions,
                                                     lastMeasures, themeProvider, visualLineage, layoutQueue);

            refreshRenderContext = new RefreshRenderContext(viewPerspective, this,
                                                            visualPositions, lastMeasures, themeProvider, visualLineage, layoutQueue);

            Container.ResolveTo <IImageProvider>(imageProvider);
            Container.ResolveTo(uiProvider);
            Container.ResolveTo(themeProvider);
        }
Пример #6
0
        public void Should_Enqueue_UniqueElements()
        {
            var target = new LayoutQueue <string>(_ => true);

            var items = new[] { "1", "2", "3", "1" };

            foreach (var item in items)
            {
                target.Enqueue(item);
            }

            Assert.Equal(3, target.Count);
            Assert.Equal(items.Take(3), target);
        }
Пример #7
0
        public void Should_Enqueue()
        {
            var target   = new LayoutQueue <string>(_ => true);
            var refQueue = new Queue <string>();
            var items    = new[] { "1", "2", "3" };

            foreach (var item in items)
            {
                target.Enqueue(item);
                refQueue.Enqueue(item);
            }

            Assert.Equal(refQueue, target);
        }
Пример #8
0
        public void Should_Dequeue()
        {
            var target   = new LayoutQueue <string>(_ => true);
            var refQueue = new Queue <string>();
            var items    = new[] { "1", "2", "3" };

            foreach (var item in items)
            {
                target.Enqueue(item);
                refQueue.Enqueue(item);
            }

            while (refQueue.Count > 0)
            {
                Assert.Equal(refQueue.Dequeue(), target.Dequeue());
            }
        }
Пример #9
0
        //public StaticGdiRenderKit(IViewPerspective viewPerspective,
        //                          IMultiSerializer xmlSerializer)
        //: this(viewPerspective, xmlSerializer)
        //{}

        public StaticGdiRenderKit(IViewPerspective viewPerspective,
                                  IMultiSerializer xmlSerializer)
            : base(new GdiImageProvider(), xmlSerializer,
                   NullSvgBuilder.Instance, null)
        {
            var defaultSurrogates = new BaseSurrogateProvider();

            var lastMeasure   = new Dictionary <IVisualElement, ValueSize>();
            var visualLineage = new VisualLineage();
            var layoutQueue   = new LayoutQueue();

            MeasureContext = new GdiMeasureContext(defaultSurrogates, lastMeasure,
                                                   BaselineThemeProvider.Instance, visualLineage, layoutQueue);

            RenderContext = new GdiRenderContext(viewPerspective,
                                                 MeasureContext.Graphics, defaultSurrogates, lastMeasure,
                                                 new Dictionary <IVisualElement, ValueCube>(),
                                                 BaselineThemeProvider.Instance, visualLineage, layoutQueue);
        }
        public OpenGLRenderKit(IFontProvider fontProvider,
                               IGLContext glContext,
                               IThemeProvider themeProvider,
                               IImageProvider imageProvider)
            : base(imageProvider, Serializer,
                   new SvgPathBuilder(imageProvider, Serializer), null)
            //: base(themeProvider, Serializer.AttributeParser,
            //    Serializer.TypeInferrer, Serializer.TypeManipulator,
            //    new Dictionary<IVisualElement, ValueCube>(), imageProvider,
            //    Serializer.AssemblyList, Serializer)
        {
            var lastMeasurements = new Dictionary <IVisualElement, ValueSize>();
            var lastRender       = new Dictionary <IVisualElement, ValueCube>();
            var visualLineage    = new VisualLineage();
            var layoutQueue      = new LayoutQueue();

            MeasureContext = new GLMeasureContext(fontProvider, this,
                                                  lastMeasurements, themeProvider, visualLineage, layoutQueue);

            RenderContext = new GLRenderContext(new BasePerspective(),
                                                glContext, fontProvider, this, themeProvider,
                                                visualLineage, lastRender, layoutQueue);
        }
Пример #11
0
        public void UpdateLayout()
        {
            base.VerifyAccess();
            if (!this._isUpdating)
            {
                this._isUpdating = true;
                WindowManager.Instance.Invalidate();
                LayoutQueue measureQueue = this.MeasureQueue;
                LayoutQueue arrangeQueue = this.ArrangeQueue;
                int         num          = 0;
                bool        flag         = true;
                UIElement   parent       = null;
                try
                {
                    this.invalidateTreeIfRecovering();
                    while (!this.MeasureQueue.IsEmpty || !this.ArrangeQueue.IsEmpty)
                    {
                        if (++num > 0x99)
                        {
                            base.Dispatcher.BeginInvoke(this._updateLayoutBackground, this);
                            parent = null;
                            flag   = false;
                            return;
                        }
                        int  num2          = 0;
                        long loopStartTime = 0L;
Label_0070:
                        if (++num2 > 0x99)
                        {
                            num2 = 0;
                            if (this.LimitExecution(ref loopStartTime))
                            {
                                parent = null;
                                flag   = false;
                                return;
                            }
                        }
                        parent = measureQueue.GetTopMost();
                        if (parent != null)
                        {
                            parent.Measure(parent._previousAvailableWidth, parent._previousAvailableHeight);
                            measureQueue.RemoveOrphans(parent);
                            goto Label_0070;
                        }
                        num2          = 0;
                        loopStartTime = 0L;
Label_00C7:
                        if (++num2 > 0x99)
                        {
                            num2 = 0;
                            if (this.LimitExecution(ref loopStartTime))
                            {
                                parent = null;
                                flag   = false;
                                return;
                            }
                        }
                        parent = arrangeQueue.GetTopMost();
                        if (parent != null)
                        {
                            int num4;
                            int num5;
                            int num6;
                            int num7;
                            this.getProperArrangeRect(parent, out num4, out num5, out num6, out num7);
                            parent.Arrange(num4, num5, num6, num7);
                            arrangeQueue.RemoveOrphans(parent);
                            goto Label_00C7;
                        }
                    }
                    parent = null;
                    flag   = false;
                }
                finally
                {
                    this._isUpdating          = false;
                    this._layoutRequestPosted = false;
                    if (flag)
                    {
                        this._gotException       = true;
                        this._forceLayoutElement = parent;
                        base.Dispatcher.BeginInvoke(this._updateLayoutBackground, this);
                    }
                }
            }
        }
Пример #12
0
        public void UpdateLayout()
        {
            VerifyAccess();

            //make UpdateLayout to be a NOP if called during UpdateLayout.
            if (_isUpdating)
            {
                return;
            }

            _isUpdating = true;

            WindowManager.Instance.Invalidate();

            LayoutQueue measureQueue = MeasureQueue;
            LayoutQueue arrangeQueue = ArrangeQueue;

            int       cnt            = 0;
            bool      gotException   = true;
            UIElement currentElement = null;

            //NOTE:
            //
            //There are a bunch of checks here that break out of and re-queue layout if
            //it looks like things are taking too long or we have somehow gotten into an
            //infinite loop.   In the TinyCLR we will probably have better ways of
            //dealing with a bad app through app domain separation, but keeping this
            //robustness can't hurt.  In a single app domain scenario, it could
            //give the opportunity to get out to the system if something is misbehaving,
            //we like this kind of reliability in embedded systems.
            //

            try
            {
                invalidateTreeIfRecovering();

                while ((!MeasureQueue.IsEmpty) || (!ArrangeQueue.IsEmpty))
                {
                    if (++cnt > 153)
                    {
                        //loop detected. Lets re-queue and let input/user to correct the situation.
                        //
                        Dispatcher.BeginInvoke(_updateLayoutBackground, this);
                        currentElement = null;
                        gotException   = false;
                        return;
                    }

                    //loop for Measure
                    //We limit the number of loops here by time - normally, all layout
                    //calculations should be done by this time, this limit is here for
                    //emergency, "infinite loop" scenarios - yielding in this case will
                    //provide user with ability to continue to interact with the app, even though
                    //it will be sluggish. If we don't yield here, the loop is goign to be a deadly one

                    int      loopCounter   = 0;
                    TimeSpan loopStartTime = TimeSpan.Zero;

                    while (true)
                    {
                        if (++loopCounter > 153)
                        {
                            loopCounter = 0;
                            if (LimitExecution(ref loopStartTime))
                            {
                                currentElement = null;
                                gotException   = false;
                                return;
                            }
                        }

                        currentElement = measureQueue.GetTopMost();

                        if (currentElement == null)
                        {
                            break;                         //exit if no more Measure candidates
                        }
                        currentElement.Measure(
                            currentElement._previousAvailableWidth,
                            currentElement._previousAvailableHeight
                            );

                        measureQueue.RemoveOrphans(currentElement);
                    }

                    //loop for Arrange
                    //if Arrange dirtied the tree go clean it again

                    //We limit the number of loops here by time - normally, all layout
                    //calculations should be done by this time, this limit is here for
                    //emergency, "infinite loop" scenarios - yielding in this case will
                    //provide user with ability to continue to interact with the app, even though
                    //it will be sluggish. If we don't yield here, the loop is goign to be a deadly one
                    loopCounter   = 0;
                    loopStartTime = TimeSpan.Zero;

                    while (true)
                    {
                        if (++loopCounter > 153)
                        {
                            loopCounter = 0;
                            if (LimitExecution(ref loopStartTime))
                            {
                                currentElement = null;
                                gotException   = false;
                                return;
                            }
                        }

                        currentElement = arrangeQueue.GetTopMost();

                        if (currentElement == null)
                        {
                            break;                         //exit if no more Arrange candidates
                        }
                        int arrangeX, arrangeY, arrangeWidth, arrangeHeight;

                        getProperArrangeRect(currentElement, out arrangeX, out arrangeY, out arrangeWidth, out arrangeHeight);

#if TINYCLR_DEBUG_LAYOUT
                        Trace.Print("arrangeWidth = " + arrangeWidth);
                        Trace.Print("arrangeHeight = " + arrangeWidth);
#endif

                        currentElement.Arrange(arrangeX, arrangeY, arrangeWidth, arrangeHeight);
                        arrangeQueue.RemoveOrphans(currentElement);
                    }

                    /* REFACTOR -- do we need Layout events and Size changed events?
                     *
                     *                  //let LayoutUpdated handlers to call UpdateLayout
                     *                  //note that it means we can get reentrancy into UpdateLayout past this point,
                     *                  //if any of event handlers call UpdateLayout sync. Need to protect from reentrancy
                     *                  //in the firing methods below.
                     *
                     *                  fireSizeChangedEvents();
                     *                  if ((!MeasureQueue.IsEmpty) || (!ArrangeQueue.IsEmpty)) continue;
                     *                  fireLayoutUpdateEvent();
                     */
                }

                currentElement = null;
                gotException   = false;
            }
            finally
            {
                _isUpdating          = false;
                _layoutRequestPosted = false;

                if (gotException)
                {
                    //set indicator
                    _gotException       = true;
                    _forceLayoutElement = currentElement;

                    //make attempt to request the subsequent layout calc
                    Dispatcher.BeginInvoke(_updateLayoutBackground, this);
                }
            }
        }