private void ProcessMaterialKeyFrames(IList <MaterialAnimationKeyFrame> frames) { if (frames == null || frames.Count == 0) { return; } processedMaterialFrameGroups = new LightList <ProcessedMaterialKeyFrameGroup>(); // todo -- ensure we release lists where we need to // todo -- dont use a list each processed frame group, use a single list sorted sensibly for (int i = 0; i < frames.Count; i++) { MaterialAnimationKeyFrame f = frames[i]; MaterialKeyFrameValue[] properties = f.properties; for (int j = 0; j < f.properties.Length; j++) { AddMaterialKeyFrame(f.key, properties[j]); } } for (int i = 0; i < processedMaterialFrameGroups.Count; i++) { MaterialPropertyId property = processedMaterialFrameGroups[i].materialIdPair; LightList <ProcessedMaterialKeyFrame> processedKeyFrames = processedMaterialFrameGroups[i].frames; processedKeyFrames.Sort(s_MaterialKeyFrameSorter); if (processedKeyFrames[0].time != 0f) { processedKeyFrames.Insert(0, new ProcessedMaterialKeyFrame(0f, default)); } } }
public void ProcessStyleKeyFrames(IList <StyleAnimationKeyFrame> frames) { if (frames == null || frames.Count == 0) { return; } processedStyleFrameGroups = new LightList <ProcessedStyleKeyFrameGroup>(); for (int i = 0; i < frames.Count; i++) { StyleAnimationKeyFrame f = frames[i]; StyleKeyFrameValue[] properties = f.properties.Array; for (int j = 0; j < f.properties.Count; j++) { AddKeyFrame(f.key, properties[j]); } } for (int i = 0; i < processedStyleFrameGroups.Count; i++) { StylePropertyId property = processedStyleFrameGroups[i].propertyId; LightList <ProcessedStyleKeyFrame> processedKeyFrames = processedStyleFrameGroups[i].frames; processedKeyFrames.Sort(s_StyleKeyFrameSorter); if (processedKeyFrames[0].time != 0f) { processedKeyFrames.Insert(0, new ProcessedStyleKeyFrame(0f, target.style.GetComputedStyleProperty(property))); } } }
// link every hole into the outer loop, producing a single-ring polygon without holes private static Node EliminateHoles(LightList <float> data, LightList <int> holeIndices, Node outerNode) { var len = holeIndices.Count; for (var i = 0; i < len; i++) { var start = holeIndices[i] * 2; var end = i < len - 1 ? holeIndices[i + 1] * 2 : data.Count; var list = LinkedList(data.Array, start, end, false); if (list == list.next) { list.steiner = true; } holeQueue.Add(GetLeftmost(list)); } holeQueue.Sort(nodeComparer); // process holes from left to right for (var i = 0; i < holeQueue.Count; i++) { EliminateHole(holeQueue[i], outerNode); outerNode = FilterPoints(outerNode, outerNode.next); } holeQueue.QuickClear(); return(outerNode); }
public AwesomeLayoutSystem(Application application) { this.application = application; this.runners = new LightList <AwesomeLayoutRunner>(); // for (int i = 0; i < application.views.Count; i++) { // runners.Add(new AwesomeLayoutRunner(this, application.views[i].dummyRoot)); // } application.onViewsSorted += uiViews => { runners.Sort((a, b) => Array.IndexOf(uiViews, b.rootElement.View) - Array.IndexOf(uiViews, a.rootElement.View)); }; application.StyleSystem.onStylePropertyChanged += HandleStylePropertyChanged; // application.StyleSystem.onStylePropertyAnimated += HandleStylepropertyAnimated; }
public VertigoRenderSystem(Camera camera, Application application) { this.camera = camera; this.commandBuffer = new CommandBuffer(); // todo -- per view this.commandBuffer.name = "UIForia Main Command Buffer"; this.renderContext = new RenderContext(application.settings); this.renderOwners = new LightList <RenderOwner>(); if (this.camera != null) { this.camera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, commandBuffer); } application.StyleSystem.onStylePropertyChanged += HandleStylePropertyChanged; application.onViewsSorted += uiViews => { renderOwners.Sort((o1, o2) => o1.view.Depth.CompareTo(o2.view.Depth)); }; }
public void Sort() { LightList <int> ints = new LightList <int>(); ints.Add(4); ints.Add(0); ints.Add(2); ints.Add(6); ints.Add(3); ints.Add(1); ints.Add(7); ints.Add(5); Comparison <int> cmp = (a, b) => a > b ? 1 : -1; ints.Sort(cmp); for (int i = 0; i < ints.Count; i++) { Assert.AreEqual(i, ints[i]); } }
private void ProcessMouseInput() { // if element does not have state requested -> hover flag, drag listener, pointer events = none, don't add // buckets feel like a lot of overhead // for each element, track if has overflowing children // if it does not and element is culled, skip directly to children's children and repeat // if aabb yMin is below screen height or aabb ymax is less than 0 -> cull // broadphase culling and input querying are related // neither uses render bounds, just obb and aabb // if dragging only attempt intersections with elements who have drag responders // if not dragging only attempt intersections with elements who have hover state (if mouse is present) or drag create or mouse / touch interactions LightList <UIElement> queryResults = (LightList <UIElement>)m_LayoutSystem.QueryPoint(mouseState.mousePosition, LightList <UIElement> .Get()); // todo -- bug! queryResults.Sort((a, b) => { int viewDepthComparison = b.View.Depth - a.View.Depth; if (viewDepthComparison != 0) { return(viewDepthComparison); } if (b.layoutBox.layer != a.layoutBox.layer) { return(b.layoutBox.layer - a.layoutBox.layer); } if (b.layoutBox.zIndex != a.layoutBox.zIndex) { return(b.layoutBox.zIndex - a.layoutBox.zIndex); } return(b.layoutBox.traversalIndex - a.layoutBox.traversalIndex); }); m_AllElementsThisFrame.Clear(); m_AllElementsThisFrame.AddRange(queryResults); if (!IsDragging) { LightList <UIElement> ancestorElements = LightList <UIElement> .Get(); if (queryResults.size > 0) { /* * Every following element must be a parent of the first. * This makes no sense for drag events but a lot for every other. */ UIElement firstElement = queryResults[0]; ancestorElements.Add(firstElement); for (int index = 1; index < queryResults.size; index++) { UIElement element = queryResults[index]; if (IsParentOf(element, firstElement)) { ancestorElements.Add(element); } } LightList <UIElement> .Release(ref queryResults); queryResults = ancestorElements; } } bool didMouseMove = mouseState.DidMove; if (didMouseMove) { for (int i = 0; i < hoveredElements.size; i++) { UIElement element = hoveredElements.array[i]; if ((element.flags & UIElementFlags.EnabledFlagSet) != UIElementFlags.EnabledFlagSet) { hoveredElements.RemoveAt(i--); continue; } if (!queryResults.Contains(element)) { hoveredElements.RemoveAt(i--); element.style.ExitState(StyleState.Hover); } } for (int i = 0; i < queryResults.Count; i++) { UIElement element = queryResults.array[i]; if ((element.style.currentState & StyleState.Hover) == 0) { hoveredElements.Add(element); element.style.EnterState(StyleState.Hover); } } } for (int i = 0; i < queryResults.Count; i++) { UIElement element = queryResults[i]; m_ElementsThisFrame.Add(element); if (!m_ElementsLastFrame.Contains(element)) { m_EnteredElements.Add(element); } if (IsMouseLeftDownThisFrame) { element.style?.EnterState(StyleState.Active); m_ActiveElements.Add(element); } } for (int i = 0; i < m_ElementsLastFrame.Count; i++) { if (!m_ElementsThisFrame.Contains(m_ElementsLastFrame[i])) { m_ExitedElements.Add(m_ElementsLastFrame[i]); } } if (IsMouseLeftUpThisFrame) { for (int i = 0; i < m_ActiveElements.Count; i++) { m_ActiveElements[i].style?.ExitState(StyleState.Active); } m_ActiveElements.Clear(); } if (!IsDragging) { CursorStyle newCursor = null; if (m_ElementsThisFrame.Count > 0) { for (int i = 0; i < m_ElementsThisFrame.Count; i++) { UIElement element = m_ElementsThisFrame[i]; if (element.isDestroyed) { continue; } if (element.style.IsDefined(StylePropertyId.Cursor)) { newCursor = element.style.Cursor; if (!newCursor.Equals(currentCursor)) { Cursor.SetCursor(newCursor.texture, newCursor.hotSpot, CursorMode.Auto); } break; } } } if (currentCursor != null && newCursor == null) { Cursor.SetCursor(null, new Vector2(0, 0), CursorMode.Auto); } currentCursor = newCursor; if (mouseState.AnyMouseDownThisFrame) { m_MouseDownElements.AddRange(m_ElementsThisFrame); } } LightList <UIElement> .Release(ref queryResults); }
private LightList <UIElement> BuildBindingUpdateList(UIElement rootElement) { LightList <UIElement> bindingUpdateList = LightList <UIElement> .Get(); if (currentDragEvent == null) { if (rootElement != null) { UIElement ptr = rootElement; while (ptr != null) { bindingUpdateList.Add(ptr); ptr = ptr.parent; } } } else { UIElement dragEventBranch = currentDragEvent.origin; UIElement rootElementBranch = rootElement; while (dragEventBranch != null || rootElementBranch != null) { if (dragEventBranch != null && rootElementBranch != null) { if (dragEventBranch.layoutBox.traversalIndex > rootElementBranch.layoutBox.traversalIndex) { bindingUpdateList.Add(dragEventBranch); dragEventBranch = dragEventBranch.parent; } else if (dragEventBranch.layoutBox.traversalIndex < rootElementBranch.layoutBox.traversalIndex) { bindingUpdateList.Add(rootElementBranch); rootElementBranch = rootElementBranch.parent; } else { while (rootElementBranch != null) { bindingUpdateList.Add(rootElementBranch); rootElementBranch = rootElementBranch.parent; } break; } } else { if (dragEventBranch == null) { bindingUpdateList.Add(rootElementBranch); rootElementBranch = rootElementBranch.parent; } else if (rootElementBranch == null) { bindingUpdateList.Add(dragEventBranch); dragEventBranch = dragEventBranch.parent; } } } } bindingUpdateList.Sort((e1, e2) => e1.layoutBox?.traversalIndex > e2.layoutBox?.traversalIndex ? -1 : 1); return(bindingUpdateList); }
// public StyleSheet Compile(string filePath, string contents) { // return Compile(filePath, StyleParser.Parse(contents)); // } // todo -- deprecate, use other method public StyleSheet Compile(string filePath, LightList <StyleASTNode> rootNodes, MaterialDatabase materialDatabase = default) { try { context = new StyleSheetConstantImporter(styleSheetImporter).CreateContext(rootNodes, materialDatabase); context.resourceManager = resourceManager; // context = new StyleCompileContext(); // todo resolve constants. should be done a per file level, should store all used constants without needing to later reference other files // StyleCompileContext.Create(styleSheetImporter) //new StyleSheetConstantImporter(styleSheetImporter).CreateContext(rootNodes); } catch (CompileException e) { e.SetFileName(filePath); throw; } context.fileName = filePath; // todo add imported style groups rootNodes.Sort((node1, node2) => { int left = (int)node1.type; int right = (int)node2.type; return(left - right); }); int containerCount = 0; int animationCount = 0; int soundCount = 0; for (int index = 0; index < rootNodes.Count; index++) { switch (rootNodes[index]) { case StyleRootNode _: containerCount++; break; case AnimationRootNode _: case SpriteSheetNode _: animationCount++; break; case SoundRootNode _: soundCount++; break; } } StyleSheet styleSheet = new StyleSheet( styleSheetImporter.ImportedStyleSheetCount, context.constants?.ToArray(), containerCount > 0 ? new UIStyleGroupContainer[containerCount] : ArrayPool <UIStyleGroupContainer> .Empty, animationCount > 0 ? new AnimationData[animationCount] : ArrayPool <AnimationData> .Empty, soundCount > 0 ? new UISoundData[soundCount] : ArrayPool <UISoundData> .Empty ); int containerIndex = 0; int animationIndex = 0; int soundIndex = 0; for (int index = 0; index < rootNodes.Count; index++) { switch (rootNodes[index]) { // we sorted the root nodes so all animations run first case SpriteSheetNode spriteSheetNode: styleSheet.animations[animationIndex] = CompileSpriteSheetAnimation(spriteSheetNode, styleSheet.animations, styleSheet.sounds); animationIndex++; break; case AnimationRootNode animNode: styleSheet.animations[animationIndex] = CompileAnimation(animNode, styleSheet.animations, styleSheet.sounds); animationIndex++; break; case SoundRootNode soundRootNode: styleSheet.sounds[soundIndex] = CompileSound(soundRootNode); soundIndex++; break; case StyleRootNode styleRoot: styleSheet.styleGroupContainers[containerIndex] = CompileStyleGroup(styleRoot, styleSheet.animations, styleSheet.sounds); styleSheet.styleGroupContainers[containerIndex].styleSheet = styleSheet; containerIndex++; break; } } context.Release(); return(styleSheet); }