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