Пример #1
0
 private void ResolveConstantReferences(StyleCompileContext context)
 {
     foreach (StyleConstant constant in context.constantsWithReferences.Values)
     {
         Resolve(context, constant);
     }
 }
Пример #2
0
        private StyleConstant ResolveReference(StyleCompileContext context, ConstReferenceNode constReference)
        {
            if (currentlyResolvingConstants.Contains(constReference.identifier))
            {
                throw new CompileException(constReference, "Circular dependency detected!");
            }

            for (int i = 0; i < context.constants.Count; i++)
            {
                StyleConstant constant = context.constants[i];
                if (constant.name == constReference.identifier)
                {
                    // reference resolved
                    return(constant);
                }
            }

            // now we have to recursively resolve the reference of the reference:
            // const x: string = @y; // we're here...
            // const y: string = @z: // ....referencing this
            // const z: string = "whatup"; // ...which will resolve to this.
            if (context.constantsWithReferences.ContainsKey(constReference.identifier))
            {
                currentlyResolvingConstants.Add(constReference.identifier);
                StyleConstant resolvedConstant = Resolve(context, context.constantsWithReferences[constReference.identifier]);
                currentlyResolvingConstants.Remove(constReference.identifier);
                return(resolvedConstant);
            }

            throw new CompileException(constReference, $"Could not resolve reference {constReference}. Known references are: " + context.PrintConstants());
        }
Пример #3
0
        public StyleCompileContext CreateContext(LightList <StyleASTNode> rootNodes, MaterialDatabase materialDatabase)
        {
            StyleCompileContext context = new StyleCompileContext(materialDatabase);

            // first all imports must be collected as they can be referenced in exports and consts
            for (int i = 0; i < rootNodes.size; i++)
            {
                switch (rootNodes[i])
                {
                case ImportNode importNode:

                    StyleSheet importedStyle = styleSheetImporter.ImportStyleSheetFromFile(importNode.source, materialDatabase);

                    LightList <StyleConstant> importedStyleConstants = new LightList <StyleConstant>(importedStyle.constants.Length);

                    for (int constantIndex = 0; constantIndex < importedStyle.constants.Length; constantIndex++)
                    {
                        StyleConstant importedStyleConstant = importedStyle.constants[constantIndex];
                        if (importedStyleConstant.exported)
                        {
                            importedStyleConstants.Add(importedStyleConstant);
                        }
                    }

                    context.importedStyleConstants.Add(importNode.alias, importedStyleConstants);

                    break;
                }
            }

            // collect all constants that could be referenced
            for (int index = 0; index < rootNodes.size; index++)
            {
                switch (rootNodes[index])
                {
                case ExportNode exportNode:
                    TransformConstNode(context, exportNode.constNode, true);
                    break;

                case ConstNode constNode:
                    TransformConstNode(context, constNode, false);
                    break;
                }
            }

            ResolveConstantReferences(context);
            context.constantsWithReferences.Clear();

            return(context);
        }
Пример #4
0
        private StyleConstant Resolve(StyleCompileContext context, StyleConstant constant)
        {
            // shortcut return for constants that have been resolved already
            for (int index = 0; index < context.constants.Count; index++)
            {
                StyleConstant c = context.constants[index];
                if (c.name == constant.name)
                {
                    return(c);
                }
            }

            StyleConstant referencedConstant;

            if (constant.constReferenceNode.children.Count > 0)
            {
                if (context.importedStyleConstants.ContainsKey(constant.constReferenceNode.identifier))
                {
                    DotAccessNode importedConstant = (DotAccessNode)constant.constReferenceNode.children[0];

                    referencedConstant = context.importedStyleConstants[constant.constReferenceNode.identifier]
                                         .Find(importedConstant.propertyName, s_FindStyleConstant);

                    if (referencedConstant.name == null)
                    {
                        throw new CompileException(importedConstant, "Could not find referenced property in imported scope.");
                    }
                }
                else
                {
                    throw new CompileException(constant.constReferenceNode, "Constants cannot reference members of other constants.");
                }
            }
            else
            {
                referencedConstant = ResolveReference(context, constant.constReferenceNode);
            }

            StyleConstant styleConstant = new StyleConstant {
                name     = constant.name,
                value    = referencedConstant.value,
                exported = constant.exported
            };

            context.constants.Add(styleConstant);
            return(styleConstant);
        }
Пример #5
0
 private void TransformConstNode(StyleCompileContext context, ConstNode constNode, bool exported)
 {
     if (constNode.value is ConstReferenceNode)
     {
         context.constantsWithReferences.Add(constNode.constName, new StyleConstant {
             name = constNode.constName,
             constReferenceNode = (ConstReferenceNode)constNode.value,
             exported           = exported
         });
     }
     else
     {
         context.constants.Add(new StyleConstant {
             name     = constNode.constName,
             value    = constNode.value,
             exported = exported
         });
     }
 }
Пример #6
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);
        }