예제 #1
0
        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));
                }
            }
        }
예제 #2
0
        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)));
                }
            }
        }
예제 #3
0
        // 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);
        }
예제 #4
0
        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;
        }
예제 #5
0
        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));
            };
        }
예제 #6
0
    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]);
        }
    }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        // 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);
        }