예제 #1
0
        private void ParseAnimationOptions(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                StyleToken typeToken  = tokenStream.Current;
                string     optionName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier).ToLower();
                bool       typeFound  = false;
                for (int index = 0; index < s_AnimationOptionNames.Length; index++)
                {
                    string name = s_AnimationOptionNames[index].Item1;
                    if (name == optionName)
                    {
                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);
                        StyleToken variableToken = tokenStream.Current;

                        AnimationOptionNode optionNode = StyleASTNodeFactory.AnimationOptionNode(s_AnimationOptionNames[index].Item2, ParsePropertyValue());
                        optionNode.WithLocation(variableToken);

                        rootNode.AddOptionNode(optionNode);

                        typeFound = true;

                        break;
                    }
                }

                if (!typeFound)
                {
                    throw new ParseException(typeToken, $"{optionName} is not a supported animation option. Valid values are: {FormatOptionList(s_AnimationOptionNames)}\n");
                }

                AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);
            }
        }
예제 #2
0
        private void ParseAnimationKeyFrames(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                string value = AssertTokenTypeAndAdvance(StyleTokenType.Number);
                AssertTokenTypeAndAdvance(StyleTokenType.Mod);

                KeyFrameNode keyFrameNode = StyleASTNodeFactory.KeyFrameNode(int.Parse(value));

                while (AdvanceIfTokenType(StyleTokenType.Comma))
                {
                    keyFrameNode.keyframes.Add(int.Parse(AssertTokenTypeAndAdvance(StyleTokenType.Number)));
                    AssertTokenTypeAndAdvance(StyleTokenType.Mod);
                }

                AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);

                while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
                {
                    ParseProperties(keyFrameNode);
                }

                rootNode.AddKeyFrameNode(keyFrameNode);
            }
        }
예제 #3
0
        private void AnimationParseLoop(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                AssertTokenTypeAndAdvance(StyleTokenType.BracketOpen);

                string identifier = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
                AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);
                if (identifier == "variables")
                {
                    ParseAnimationVariables(rootNode);
                }
                else if (identifier == "keyframes")
                {
                    ParseAnimationKeyFrames(rootNode);
                }
                else if (identifier == "options")
                {
                    ParseAnimationOptions(rootNode);
                }
                else if (identifier == "triggers")
                {
                }
            }
        }
예제 #4
0
    public void ParseKeyFrames()
    {
        LightList <StyleASTNode> nodes = StyleParser.Parse(@"
            animation anim1 {
                [keyframes] {
                    0% { BackgroundColor = red; }
                    100% { BackgroundColor = green; }
                }
            }
        ");

        Assert.AreEqual(1, nodes.Count);
        AnimationRootNode rootNode = nodes[0] as AnimationRootNode;

        KeyFrameNode keyFrameNode0 = rootNode.keyframeNodes[0];

        Assert.AreEqual(0, keyFrameNode0.keyframes[0]);
        Assert.AreEqual(1, keyFrameNode0.children.Count);
        Assert.AreEqual(StyleASTNodeType.Property, keyFrameNode0.children[0].type);

        KeyFrameNode keyFrameNode1 = rootNode.keyframeNodes[1];

        Assert.AreEqual(100, keyFrameNode1.keyframes[0]);
        Assert.AreEqual(1, keyFrameNode1.children.Count);
        Assert.AreEqual(StyleASTNodeType.Property, keyFrameNode1.children[0].type);
    }
예제 #5
0
        private void ParseAnimation()
        {
            StyleToken        initialStyleToken = tokenStream.Current;
            AnimationRootNode animRoot          = StyleASTNodeFactory.AnimationRootNode(initialStyleToken);

            animRoot.WithLocation(initialStyleToken);
            tokenStream.Advance();
            AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);
            AnimationParseLoop(animRoot);
            nodes.Add(animRoot);
        }
예제 #6
0
        protected AnimationGraph(string path, AnimationRootNode root, AnimationGraphContext context)
        {
            Ensure.That(path, nameof(path)).IsNotNull();
            Ensure.That(root, nameof(root)).IsNotNull();
            Ensure.That(context, nameof(context)).IsNotNull();

            Key     = path;
            Root    = root;
            Context = context;
            Logger  = context.LoggerFactory.CreateLogger(this.GetLogCategory());
        }
예제 #7
0
        private AnimationData CompileAnimation(AnimationRootNode animNode, AnimationData[] styleSheetAnimations, UISoundData[] uiSoundData)
        {
            AnimationData data = new AnimationData();

            data.name          = animNode.animName;
            data.fileName      = context.fileName;
            data.animationType = AnimationType.KeyFrame;
            data.frames        = CompileKeyFrames(animNode, styleSheetAnimations, uiSoundData);
            data.options       = CompileAnimationOptions(animNode);
            return(data);
        }
예제 #8
0
        protected virtual Option <IAnimationGraph> TryCreate(
            string path, AnimationRootNode node, AnimationGraphContext context)
        {
            Ensure.That(node, nameof(node)).IsNotNull();

            Option <IAnimationGraph> graph = None;

            switch (node)
            {
            case AnimationNodeStateMachine states:
                graph = new AnimationStates(path, states, context);
                break;

            case AnimationNodeBlendTree blendTree:
                graph = new BlendTree(path, blendTree, context);
                break;
            }

            graph.Iter(g => g.Initialize());

            return(graph);
        }
예제 #9
0
    public void ParseAnimationVariableHeader()
    {
        LightList <StyleASTNode> nodes = StyleParser.Parse(@"
            animation anim1 {
                [variables] {
                    float val = 127;
                }
            }
        ");

        Assert.AreEqual(1, nodes.Count);
        Assert.IsInstanceOf <AnimationRootNode>(nodes[0]);
        AnimationRootNode rootNode = nodes[0] as AnimationRootNode;

        Assert.AreEqual("anim1", rootNode.animName);
        Assert.AreEqual(1, rootNode.variableNodes.Count);
        VariableDefinitionNode varNode = rootNode.variableNodes[0];

        Assert.AreEqual("val", varNode.name);
        Assert.AreEqual(typeof(float), varNode.variableType);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, varNode.value.type);
    }
예제 #10
0
        private void ParseAnimationVariables(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                StyleToken typeToken      = tokenStream.Current;
                string     typeIdentifier = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                bool       typeFound      = false;
                for (int index = 0; index < s_SupportedVariableTypes.Length; index++)
                {
                    (string name, Type type) = s_SupportedVariableTypes[index];
                    if (name == typeIdentifier)
                    {
                        string variableName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);
                        StyleToken variableToken = tokenStream.Current;

                        VariableDefinitionNode varNode = new VariableDefinitionNode();
                        varNode.name         = variableName;
                        varNode.variableType = type;
                        varNode.value        = ParsePropertyValue();
                        varNode.WithLocation(variableToken);

                        rootNode.AddVariableNode(varNode);

                        typeFound = true;

                        break;
                    }
                }

                if (!typeFound)
                {
                    throw new ParseException(typeToken, "Unsupported Type; please read the manual!");
                }

                AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);
            }
        }
예제 #11
0
 public Option <IAnimationGraph> TryCreate(AnimationRootNode node, AnimationGraphContext context) =>
 TryCreate(string.Empty, node, context);
예제 #12
0
    public void ParseAnimationOptionsHeader()
    {
        LightList <StyleASTNode> nodes = StyleParser.Parse(@"
            animation anim1 {
                [options] {
                    delay = 127;
                    loopType = constant;
                    loopTime = 100;
                    iterations = 99;
                    duration = 34;
                    forwardStartDelay = 1;
                    reverseStartDelay = 1;
                    direction = forward;
                    timingFunction = linear;
                }
            }
        ");

        Assert.AreEqual(1, nodes.Count);
        AnimationRootNode rootNode = nodes[0] as AnimationRootNode;

        AnimationOptionNode opt0 = rootNode.optionNodes[0];

        Assert.AreEqual("delay", opt0.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt0.value.type);

        AnimationOptionNode opt1 = rootNode.optionNodes[1];

        Assert.AreEqual("loopType", opt1.optionName);
        Assert.AreEqual(StyleASTNodeType.Identifier, opt1.value.type);

        AnimationOptionNode opt2 = rootNode.optionNodes[2];

        Assert.AreEqual("loopTime", opt2.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt2.value.type);

        AnimationOptionNode opt3 = rootNode.optionNodes[3];

        Assert.AreEqual("iterations", opt3.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt3.value.type);

        AnimationOptionNode opt4 = rootNode.optionNodes[4];

        Assert.AreEqual("duration", opt4.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt4.value.type);

        AnimationOptionNode opt5 = rootNode.optionNodes[5];

        Assert.AreEqual("forwardStartDelay", opt5.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt5.value.type);

        AnimationOptionNode opt6 = rootNode.optionNodes[6];

        Assert.AreEqual("reverseStartDelay", opt6.optionName);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, opt6.value.type);

        AnimationOptionNode opt7 = rootNode.optionNodes[7];

        Assert.AreEqual("direction", opt7.optionName);
        Assert.AreEqual(StyleASTNodeType.Identifier, opt7.value.type);

        AnimationOptionNode opt8 = rootNode.optionNodes[8];

        Assert.AreEqual("timingFunction", opt8.optionName);
        Assert.AreEqual(StyleASTNodeType.Identifier, opt8.value.type);
    }
예제 #13
0
    public void ParseAnimationVariableHeaderMultipleValues()
    {
        LightList <StyleASTNode> nodes = StyleParser.Parse(@"
            animation anim1 {
                [variables] {
                    float val = 127;
                    UIMeasurement measure = 0.4pca;
                    Measurement measure2 = 0.5pca;
                    UIFixedLength fm1 = 40px;
                    FixedLength fm2 = 50px;
                    TransformOffset t1 = 70px;
                    Offset t2 = 80px;
                    int i = 10;
                    Color c = #11223344;
                    int ref = @intref;
                    
                }
            }
        ");

        Assert.AreEqual(1, nodes.Count);
        Assert.IsInstanceOf <AnimationRootNode>(nodes[0]);
        AnimationRootNode rootNode = nodes[0] as AnimationRootNode;

        Assert.AreEqual("anim1", rootNode.animName);
        Assert.AreEqual(10, rootNode.variableNodes.Count);
        VariableDefinitionNode varNode0 = rootNode.variableNodes[0];

        Assert.AreEqual("val", varNode0.name);
        Assert.AreEqual(typeof(float), varNode0.variableType);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, varNode0.value.type);

        VariableDefinitionNode varNode1 = rootNode.variableNodes[1];

        Assert.AreEqual("measure", varNode1.name);
        Assert.AreEqual(typeof(UIMeasurement), varNode1.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode1.value.type);

        VariableDefinitionNode varNode2 = rootNode.variableNodes[2];

        Assert.AreEqual("measure2", varNode2.name);
        Assert.AreEqual(typeof(UIMeasurement), varNode2.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode2.value.type);

        VariableDefinitionNode varNode3 = rootNode.variableNodes[3];

        Assert.AreEqual("fm1", varNode3.name);
        Assert.AreEqual(typeof(UIFixedLength), varNode3.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode3.value.type);

        VariableDefinitionNode varNode4 = rootNode.variableNodes[4];

        Assert.AreEqual("fm2", varNode4.name);
        Assert.AreEqual(typeof(UIFixedLength), varNode4.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode4.value.type);

        VariableDefinitionNode varNode5 = rootNode.variableNodes[5];

        Assert.AreEqual("t1", varNode5.name);
        Assert.AreEqual(typeof(OffsetMeasurement), varNode5.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode5.value.type);

        VariableDefinitionNode varNode6 = rootNode.variableNodes[6];

        Assert.AreEqual("t2", varNode6.name);
        Assert.AreEqual(typeof(OffsetMeasurement), varNode6.variableType);
        Assert.AreEqual(StyleASTNodeType.Measurement, varNode6.value.type);

        VariableDefinitionNode varNode7 = rootNode.variableNodes[7];

        Assert.AreEqual("i", varNode7.name);
        Assert.AreEqual(typeof(int), varNode7.variableType);
        Assert.AreEqual(StyleASTNodeType.NumericLiteral, varNode7.value.type);

        VariableDefinitionNode varNode8 = rootNode.variableNodes[8];

        Assert.AreEqual("c", varNode8.name);
        Assert.AreEqual(typeof(Color), varNode8.variableType);
        Assert.AreEqual(StyleASTNodeType.Color, varNode8.value.type);

        VariableDefinitionNode varNode9 = rootNode.variableNodes[9];

        Assert.AreEqual("ref", varNode9.name);
        Assert.AreEqual(typeof(int), varNode9.variableType);
        Assert.AreEqual(StyleASTNodeType.Reference, varNode9.value.type);
    }
예제 #14
0
        private AnimationOptions CompileAnimationOptions(AnimationRootNode animNode)
        {
            AnimationOptions options = new AnimationOptions();

            if (animNode.optionNodes == null)
            {
                return(options);
            }

            LightList <AnimationOptionNode> optionNodes = animNode.optionNodes;

            if (optionNodes == null)
            {
                return(options);
            }

            for (int i = 0; i < optionNodes.Count; i++)
            {
                string       optionName = optionNodes[i].optionName.ToLower();
                StyleASTNode value      = optionNodes[i].value;

                switch (optionName)
                {
                case "duration":
                    options.duration = StylePropertyMappers.MapUITimeMeasurement(value, context);
                    break;

                case "iterations":
                    options.iterations = (int)StylePropertyMappers.MapNumberOrInfinite(value, context);
                    break;

                case "looptime":
                    options.loopTime = StylePropertyMappers.MapNumber(value, context);
                    break;

                case "delay":
                    options.delay = StylePropertyMappers.MapUITimeMeasurement(value, context);
                    break;

                case "direction":
                    options.direction = StylePropertyMappers.MapEnum <AnimationDirection>(value, context);
                    break;

                case "looptype":
                    options.loopType = StylePropertyMappers.MapEnum <AnimationLoopType>(value, context);
                    break;

                case "forwardstartdelay":
                    options.forwardStartDelay = (int)StylePropertyMappers.MapNumber(value, context);
                    break;

                case "reversestartdelay":
                    options.reverseStartDelay = (int)StylePropertyMappers.MapNumber(value, context);
                    break;

                case "timingfunction":
                    options.timingFunction = StylePropertyMappers.MapEnum <EasingFunction>(value, context);
                    break;

                default:
                    throw new CompileException(optionNodes[i], "Invalid option argument for animation");
                }
            }

            return(options);
        }
예제 #15
0
        private unsafe StyleAnimationKeyFrame[] CompileKeyFrames(AnimationRootNode animNode, AnimationData[] styleSheetAnimations, UISoundData[] uiSoundData)
        {
            if (animNode.keyframeNodes == null)
            {
                // todo throw error or log warning?
                return(new StyleAnimationKeyFrame[0]);
            }

            int keyframeCount = 0;

            for (int i = 0; i < animNode.keyframeNodes.Count; i++)
            {
                keyframeCount += animNode.keyframeNodes[i].keyframes.Count;
            }

            StyleAnimationKeyFrame[] frames = new StyleAnimationKeyFrame[keyframeCount];

            int nextKeyframeIndex = 0;

            for (int i = 0; i < animNode.keyframeNodes.Count; i++)
            {
                KeyFrameNode keyFrameNode = animNode.keyframeNodes[i];

                // todo -- this is madness and not working, fix it!!!!!!!
                for (int j = 0; j < keyFrameNode.children.Count; j++)
                {
                    StyleASTNode keyFrameProperty = keyFrameNode.children[j];
                    if (keyFrameProperty is PropertyNode propertyNode)
                    {
                        StylePropertyMappers.MapProperty(s_ScratchStyle, propertyNode, context);
                    }
                    else if (keyFrameProperty is MaterialPropertyNode materialPropertyNode)
                    {
                        string materialName = materialPropertyNode.materialName;

                        if (context.materialDatabase.TryGetBaseMaterialId(materialName, out MaterialId materialId))
                        {
                            if (context.materialDatabase.TryGetMaterialProperty(materialId, materialPropertyNode.identifier, out MaterialPropertyInfo propertyInfo))
                            {
                                fixed(char *charptr = materialPropertyNode.value)
                                {
                                    CharStream            stream = new CharStream(charptr, 0, (uint)materialPropertyNode.value.Length);
                                    MaterialKeyFrameValue kfv    = default;

                                    switch (propertyInfo.propertyType)
                                    {
                                    case MaterialPropertyType.Color:

                                        if (stream.TryParseColorProperty(out Color32 color))
                                        {
                                            kfv = new MaterialKeyFrameValue(materialId, propertyInfo.propertyId, new MaterialPropertyValue2()
                                            {
                                                colorValue = color
                                            });
                                        }

                                        break;

                                    case MaterialPropertyType.Float:
                                        if (stream.TryParseFloat(out float floatVal))
                                        {
                                            kfv = new MaterialKeyFrameValue(materialId, propertyInfo.propertyId, new MaterialPropertyValue2()
                                            {
                                                floatValue = floatVal
                                            });
                                        }
                                        break;

                                    case MaterialPropertyType.Vector:
                                        break;

                                    case MaterialPropertyType.Range:
                                        break;

                                    case MaterialPropertyType.Texture:
                                        break;

                                    default:
                                        throw new ArgumentOutOfRangeException();
                                    }
                                }
                            }
                        }
                    }
                }

                StructList <StyleKeyFrameValue> styleKeyValues = new StructList <StyleKeyFrameValue>(s_ScratchStyle.PropertyCount);

                for (int j = 0; j < s_ScratchStyle.PropertyCount; j++)
                {
                    styleKeyValues[j] = new StyleKeyFrameValue(s_ScratchStyle[j]);
                }

                styleKeyValues.size = s_ScratchStyle.PropertyCount;

                for (int keyframeIndex = 0; keyframeIndex < keyFrameNode.keyframes.Count; keyframeIndex++)
                {
                    float time = keyFrameNode.keyframes[keyframeIndex] / 100f;

                    frames[nextKeyframeIndex] = new StyleAnimationKeyFrame(time)
                    {
                        properties = styleKeyValues
                    };

                    nextKeyframeIndex++;
                }

                s_ScratchStyle.PropertyCount = 0;
            }

            return(frames);
        }