Exemple #1
0
        /// <summary>
        /// Consumes the stream only if the current token belongs to a command definition.
        /// </summary>
        /// <param name="styleRootNode"></param>
        /// <returns>true in case the current token belongs to a command definition. False if it does not.</returns>
        private bool TryParseCommand(StyleNodeContainer styleRootNode)
        {
            switch (tokenStream.Current.styleTokenType)
            {
            case StyleTokenType.Exit:
                tokenStream.Advance();
                AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Exit, ParseCommandAttribute()));
                return(true);

            case StyleTokenType.Enter:
                tokenStream.Advance();
                AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, ParseCommandAttribute()));
                return(true);

            case StyleTokenType.EnterExit:
                tokenStream.Advance();
                AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.EnterExit, ParseCommandAttribute()));
                return(true);

            default:
                return(false);
            }
        }
Exemple #2
0
 private void ParseProperties(StyleNodeContainer styleRootNode)
 {
     while (tokenStream.HasMoreTokens && tokenStream.Current.styleTokenType != StyleTokenType.BracesClose)
     {
         ParseProperty(styleRootNode);
     }
 }
Exemple #3
0
        private void ParseStateOrAttributeGroup(StyleNodeContainer styleRootNode)
        {
            switch (tokenStream.Current.styleTokenType)
            {
            // this is the state group
            case StyleTokenType.Identifier:
                StyleStateContainer stateGroupRootNode = StyleASTNodeFactory.StateGroupRootNode(tokenStream.Current);

                tokenStream.Advance();
                AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
                AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);

                ParseProperties(stateGroupRootNode);

                AssertTokenTypeAndAdvance(StyleTokenType.BracesClose);

                styleRootNode.AddChildNode(stateGroupRootNode);

                break;

            case StyleTokenType.AttributeSpecifier:
                ParseAttributeGroup();
                break;

            default:
                throw new ParseException(tokenStream.Current, "Expected either a group state identifier (hover etc.)" + " or an attribute identifier (attr:...)");
            }
        }
Exemple #4
0
        private void ParseProperty(StyleNodeContainer styleRootNode, bool parsingKeyframes = false)
        {
            StyleToken propertyNodeToken = tokenStream.Current;
            string     propertyName;

            if (AdvanceIfTokenType(StyleTokenType.Cursor))
            {
                propertyName = propertyNodeToken.value;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Run))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Run));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Pause))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Pause));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Stop))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Stop));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.BracketOpen))
            {
                if (TryParseCommand(styleRootNode))
                {
                    return;
                }

                throw new ParseException(tokenStream.Current, "Not sure what you tried here but at this point only [enter] and [exit] run animation would be legal.");
            }
            else
            {
                propertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                if (propertyName == "material" || propertyName == "Material")
                {
                    if (tokenStream.Current == StyleTokenType.Colon)
                    {
                        tokenStream.Advance();

                        string materialName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                        AssertTokenTypeAndAdvance(StyleTokenType.Dot);

                        string materialPropertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);

                        TextUtil.StringBuilder.Clear();

                        while (tokenStream.HasMoreTokens && tokenStream.Current != StyleTokenType.EndStatement)
                        {
                            TextUtil.StringBuilder.Append(tokenStream.Current.value);
                            tokenStream.Advance();
                        }

                        tokenStream.Advance();

                        MaterialPropertyNode materialPropertyNode = new MaterialPropertyNode {
                            materialName = materialName,
                            identifier   = materialPropertyName,
                            value        = TextUtil.StringBuilder.ToString()
                        };

                        TextUtil.StringBuilder.Clear();

                        materialPropertyNode.WithLocation(propertyNodeToken);
                        styleRootNode.AddChildNode(materialPropertyNode);
                        return;
                    }
                }
            }

            AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);

            PropertyNode propertyNode = StyleASTNodeFactory.PropertyNode(propertyName);

            propertyNode.WithLocation(propertyNodeToken);

            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.EndStatement))
            {
                propertyNode.AddChildNode(ParsePropertyValue());
                // we just ignore the comma for now
                AdvanceIfTokenType(StyleTokenType.Comma);
            }

            styleRootNode.AddChildNode(propertyNode);
        }
Exemple #5
0
        private void ParseStyleGroupBody(StyleNodeContainer styleRootNode)
        {
            AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);

            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                switch (tokenStream.Current.styleTokenType)
                {
                case StyleTokenType.Not: {
                    groupOperatorStack.Push(StyleOperatorType.Not);
                    tokenStream.Advance();
                    ParseAttributeOrExpressionGroup();
                    break;
                }

                case StyleTokenType.And:
                    tokenStream.Advance();
                    if (AdvanceIfTokenType(StyleTokenType.Not))
                    {
                        groupOperatorStack.Push(StyleOperatorType.Not);
                    }

                    ParseAttributeOrExpressionGroup();
                    break;

                case StyleTokenType.BracketOpen:
                    tokenStream.Advance();
                    if (!TryParseCommand(styleRootNode))
                    {
                        ParseStateOrAttributeGroup(styleRootNode);
                    }

                    break;

                case StyleTokenType.Cursor:
                    // special case here: we are out of words and need to use the
                    // cursor token for the property AND the top level definition ¯\_(ツ)_/¯
                    ParseProperty(styleRootNode);
                    break;

                case StyleTokenType.Identifier:
                    ParseProperty(styleRootNode);
                    break;

                case StyleTokenType.Run:
                    tokenStream.Advance();
                    styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Run));
                    break;

                case StyleTokenType.Stop:
                    tokenStream.Advance();
                    styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Stop));
                    break;

                case StyleTokenType.Pause:
                    tokenStream.Advance();
                    styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Pause));
                    break;

                case StyleTokenType.BracesOpen: {
                    // At this point only unconsumed attribute/expression group bodies are allowed

                    if (groupExpressionStack.Count > 1)
                    {
                        throw new ParseException(tokenStream.Current, "There was a problem, I somehow made an error parsing a combined style group...");
                    }

                    if (groupExpressionStack.Count == 1)
                    {
                        AttributeNodeContainer attributeNodeContainer = groupExpressionStack.Pop();
                        ParseStyleGroupBody(attributeNodeContainer);
                        styleRootNode.AddChildNode(attributeNodeContainer);
                    }
                    else
                    {
                        throw new ParseException(tokenStream.Current, "Expected an attribute style group body. Braces are in a weird position!");
                    }

                    break;
                }

                default:
                    throw new ParseException(tokenStream.Current, "Expected either a boolean group operator (not / and), the start" + " of a group (an open bracket) or a regular property identifier but found " + tokenStream.Current.styleTokenType + " with value " + tokenStream.Current.value);
                }
            }
        }
Exemple #6
0
        private void CompileStyleGroups(StyleNodeContainer root, StyleType styleType, LightList <UIStyleGroup> groups, UIStyleGroup targetGroup, AnimationData[] styleSheetAnimations, UISoundData[] uiSoundData)
        {
            for (int index = 0; index < root.children.Count; index++)
            {
                StyleASTNode node = root.children[index];
                switch (node)
                {
                case SelectNode selectNode:
                    break;

                case PropertyNode propertyNode:
                    // add to normal ui style set
                    StylePropertyMappers.MapProperty(targetGroup.normal.style, propertyNode, context);
                    break;

                case AttributeNodeContainer attribute:
                    if (root is AttributeNodeContainer)
                    {
                        throw new CompileException(attribute, "You cannot nest attribute group definitions.");
                    }

                    UIStyleGroup attributeGroup = new UIStyleGroup();
                    attributeGroup.normal    = UIStyleRunCommand.CreateInstance();
                    attributeGroup.name      = root.identifier;
                    attributeGroup.rule      = MapAttributeContainerToRule(attribute);
                    attributeGroup.styleType = styleType;
                    groups.Add(attributeGroup);
                    CompileStyleGroups(attribute, styleType, groups, attributeGroup, styleSheetAnimations, uiSoundData);

                    break;

                case RunNode runNode:
                    UIStyleRunCommand cmd = new UIStyleRunCommand()
                    {
                        style       = targetGroup.normal.style,
                        runCommands = targetGroup.normal.runCommands ?? new LightList <IRunCommand>(4)
                    };

                    if (runNode.command is AnimationCommandNode animationCommandNode)
                    {
                        MapAnimationCommand(styleSheetAnimations, cmd, animationCommandNode);
                    }
                    else if (runNode.command is SoundCommandNode soundCommandNode)
                    {
                        MapSoundCommand(uiSoundData, cmd, soundCommandNode);
                    }

                    targetGroup.normal = cmd;
                    break;

                case StyleStateContainer styleContainer:
                    if (styleContainer.identifier == "hover")
                    {
                        UIStyleRunCommand uiStyleRunCommand = targetGroup.hover;
                        uiStyleRunCommand.style = uiStyleRunCommand.style ?? new UIStyle();
                        MapProperties(styleSheetAnimations, uiSoundData, ref uiStyleRunCommand, styleContainer.children);
                        targetGroup.hover = uiStyleRunCommand;
                    }
                    else if (styleContainer.identifier == "focus")
                    {
                        UIStyleRunCommand uiStyleRunCommand = targetGroup.focused;
                        uiStyleRunCommand.style = uiStyleRunCommand.style ?? new UIStyle();
                        MapProperties(styleSheetAnimations, uiSoundData, ref uiStyleRunCommand, styleContainer.children);
                        targetGroup.focused = uiStyleRunCommand;
                    }
                    else if (styleContainer.identifier == "active")
                    {
                        UIStyleRunCommand uiStyleRunCommand = targetGroup.active;
                        uiStyleRunCommand.style = uiStyleRunCommand.style ?? new UIStyle();
                        MapProperties(styleSheetAnimations, uiSoundData, ref uiStyleRunCommand, styleContainer.children);
                        targetGroup.active = uiStyleRunCommand;
                    }
                    else
                    {
                        throw new CompileException(styleContainer, $"Unknown style state '{styleContainer.identifier}'. Please use [hover], [focus] or [active] instead.");
                    }

                    break;

                default:
                    throw new CompileException(node, $"You cannot have a {node} at this level.");
                }
            }
        }