Esempio n. 1
0
        public static void FindDrawables(Compiler compiler, DrawBlock block, bool createImplicitDrawableBlockIfNoExplicitAreFound)
        {
            Expression obj = null;

            if (!block.Method.IsStatic)
            {
                obj = new This(block.Source, compiler.TypeBuilder.Parameterize(block.Method.DeclaringType)).Address;
            }

            var result = new List <Drawable>();
            var path   = new List <Drawable.Node> {
                new Drawable.Node(obj, block)
            };

            FindDrawables(compiler, block, path, new List <Drawable.Node>(), result);

            if (result.Count == 0 && createImplicitDrawableBlockIfNoExplicitAreFound)
            {
                // Add an implicit drawable block when no explicit drawable blocks are found
                block.Members.Add(new Node(new MetaBlock(block.Source, block, ".implicit", MetaBlockType.Drawable)));

                path = new List <Drawable.Node> {
                    new Drawable.Node(obj, block)
                };
                FindDrawables(compiler, block, path, new List <Drawable.Node>(), result);
            }

            result.Reverse();
            block.SetDrawables(result.ToArray());
        }
Esempio n. 2
0
        void ApplyLambdaBlock(AstBlock ast, DrawBlock parent, Block result)
        {
            if (ast.UsingBlocks == null)
            {
                var usingBlocks = new List <Block>();

                for (int j = 0, l = result.Members.Count; j < l; j++)
                {
                    var apply = result.Members[j] as Apply;

                    if (apply != null)
                    {
                        usingBlocks.Add(apply.Block);
                    }
                }

                result.SetUsingBlocks(usingBlocks.ToArray());
            }

            Expression obj = null;

            if (!parent.Method.IsStatic)
            {
                obj = new This(parent.Source, _compiler.TypeBuilder.Parameterize(parent.Method.DeclaringType)).Address;
            }

            parent.Members.Add(new Apply(ast.Name.Source, 0, result, obj));
        }
Esempio n. 3
0
        public Statement CompileDraw(Function func, List <VariableScope> vscopeStack, AstDraw draw)
        {
            var method = func as Method;

            if (method == null || method.IsStatic ||
                !method.DeclaringType.Methods.Contains(method))
            {
                Log.Error(draw.Source, ErrorCode.E3222, "'draw' is not allowed in this scope because " + func.Quote() + " is not a non-static method");
                return(Expression.Invalid);
            }

            var parent = method.DeclaringType as ClassType;

            if (parent == null || parent.IsFlattenedDefinition)
            {
                Log.Error(draw.Source, ErrorCode.E3223, "'draw' is not allowed in this scope because " + method.DeclaringType.Quote() + " is not a non-generic class");
                return(Expression.Invalid);
            }

            var result = new DrawBlock(draw.Source, parent, method, FlattenVariableScopes(vscopeStack));

            method.DrawBlocks.Add(result);

            EnqueueBlock(result, x => PopulateBlock(draw.Block, x));
            _enqueuedDrawClasses.Add(method.DeclaringType);

            return(result.DrawScope);
        }
Esempio n. 4
0
        static Expression ResolveApplyInstance(Pass parent, DrawBlock drawBlock, Expression applyObj, Expression parentInst)
        {
            if (applyObj != null)
            {
                applyObj = applyObj.CopyExpression(new CopyState(drawBlock.Method));
                new MetaObjectReplacer(parent, parentInst).VisitNullable(ref applyObj, ExpressionUsage.Object);
                return(applyObj);
            }

            return(null);
        }
Esempio n. 5
0
        static DrawBlock CreateFlattenedVirtualApplyInDrawBlock(Source src, DrawBlock drawBlock, int ApplyIndex, Expression obj, Block instBlock)
        {
            var result = new DrawBlock(drawBlock);

            for (int i = 0, l = drawBlock.Members.Count; i < l; i++)
            {
                result.Members.Add(i != ApplyIndex
                    ? drawBlock.Members[i]
                    : new Apply(src, ApplyModifier.Sealed, instBlock, obj));
            }

            return(result);
        }
Esempio n. 6
0
        static void ClosePath(Pass parent, DrawBlock drawBlock, List <Drawable.Node> result)
        {
            var n = result.Last();

            if (n.Top != 0)
            {
                throw new FatalException(n.Block.Source, ErrorCode.I0075, "DrawableExposer: n.Top != 0");
            }

            if (n.Block is Block && n.Block.IsNestedType && n.Block.ParentType.Block == n.Block)
            {
                var dt = n.Block.ParentType;

                if (dt.Base?.Block != null)
                {
                    ExpandNode(parent, drawBlock, new Drawable.Node(n.Object, dt.Base.Block), result);
                    ClosePath(parent, drawBlock, result);
                }
            }
        }
Esempio n. 7
0
        static void ExpandNode(Pass parent, DrawBlock drawBlock, Drawable.Node n, List <Drawable.Node> result)
        {
            for (int i = n.Bottom; i >= n.Top; i--)
            {
                var item = n.Block.Members[i];

                if (item is Node)
                {
                    result.Add(new Drawable.Node(n.Object, n.Block, i + 1, n.Bottom));
                    n.Bottom = i - 1;
                }
                else if (item is Apply)
                {
                    result.Add(new Drawable.Node(n.Object, n.Block, i + 1, n.Bottom));
                    n.Bottom = i - 1;

                    var apply = item as Apply;
                    ExpandNode(parent, drawBlock, new Drawable.Node(ResolveApplyInstance(parent, drawBlock, apply.Object, n.Object), apply.Block), result);
                    ClosePath(parent, drawBlock, result);
                }
            }

            result.Add(n);
        }
Esempio n. 8
0
 public static IPlayable Draw(Controller c, IPlayable cardToDraw = null)
 {
     return(DrawBlock.Invoke(c, cardToDraw));
 }
Esempio n. 9
0
        static void FindDrawables(Compiler compiler, DrawBlock drawBlock, List <Drawable.Node> lower, List <Drawable.Node> upper, List <Drawable> result)
        {
            var n = lower.RemoveLast();

            // If node contains any information, add node source to list of sources
            if (!n.Block.Source.IsUnknown && n.Bottom >= n.Top)
            {
                drawBlock.Method.DeclaringType.SourceFiles.Add(n.Block.Source.FullPath);
            }

            for (int i = n.Bottom; i >= n.Top; i--)
            {
                var item = n.Block.Members[i];

                if (item is Node)
                {
                    var node = item as Node;

                    upper.Add(new Drawable.Node(n.Object, n.Block, n.Top, i - 1));
                    lower.Add(new Drawable.Node(n.Object, n.Block, i + 1, n.Bottom));
                    lower.Add(new Drawable.Node(n.Object, node.Block));

                    if (node.Block.MetaBlockType == MetaBlockType.Drawable)
                    {
                        var dp = new List <Drawable.Node>();

                        for (int j = 0; j < lower.Count; j++)
                        {
                            ExpandNode(compiler.Pass, drawBlock, lower[j], dp);
                        }

                        for (int j = upper.Count - 1; j >= 0; j--)
                        {
                            ExpandNode(compiler.Pass, drawBlock, upper[j], dp);
                            ClosePath(compiler.Pass, drawBlock, dp);
                        }

                        dp.Add(new Drawable.Node(null, compiler.BlockBuilder.TerminalProperties));
                        dp.Reverse();

                        result.Add(new Drawable(drawBlock, node.Block, dp.ToArray()));
                    }

                    FindDrawables(compiler, drawBlock, lower, upper, result);

                    lower.RemoveLast();
                    upper.RemoveLast();
                }
                else if (item is Apply)
                {
                    var apply = item as Apply;

                    upper.Add(new Drawable.Node(n.Object, n.Block, n.Top, i - 1));
                    lower.Add(new Drawable.Node(n.Object, n.Block, i + 1, n.Bottom));

                    lower.Add(new Drawable.Node(ResolveApplyInstance(compiler.Pass, drawBlock, apply.Object, n.Object), apply.Block));

                    FindDrawables(compiler, drawBlock, lower, upper, result);

                    lower.RemoveLast();
                    upper.RemoveLast();
                }
            }

            if (n.Block is Block && n.Block.IsNestedType && n.Block.ParentType.Block == n.Block)
            {
                var dt = n.Block.ParentType;

                if (dt.Base?.Block != null)
                {
                    lower.Add(n);
                    lower.Add(new Drawable.Node(n.Object, dt.Base.Block));

                    FindDrawables(compiler, drawBlock, lower, upper, result);

                    lower.RemoveLast();
                }
            }
        }
Esempio n. 10
0
 public Expression AddProgram(DrawBlock block, Expression program)
 {
     return(AddCached("Shader", () => program, block.Method.DeclaringType.UnoName, block));
 }
Esempio n. 11
0
        static bool TrySplitVirtualAppliesInDrawBlockRecursive(Compiler compiler, DrawBlock drawBlock, ref int drawBlockIndex, HashSet <Scope> drawScopes)
        {
            for (int i = 0, l = drawBlock.Members.Count; i < l; i++)
            {
                var apply = drawBlock.Members[i] as Apply;

                if (apply != null &&
                    apply.Modifier == ApplyModifier.Virtual &&
                    apply.Object != null)
                {
                    var dt        = apply.Object.ReturnType;
                    int baseIndex = drawBlockIndex;

                    Statement root   = null;
                    IfElse    lastIf = null;

                    HashSet <DataType> subSet;
                    if (compiler.BlockBuilder.FlattenedTypes.TryGetValue(dt, out subSet))
                    {
                        var subArray = subSet.ToArray();

                        // Make sure array is sorted correctly.
                        // Reverse order since this is most similar to the original order making sorting ~O(n)

                        Array.Sort(subArray,
                                   (a, b) =>
                        {
                            int al = 0, bl = 0;

                            for (var bt = a.Base; bt != null && bt != dt; bt = bt.Base)
                            {
                                al++;
                            }
                            for (var bt = b.Base; bt != null && bt != dt; bt = bt.Base)
                            {
                                bl++;
                            }

                            return(al - bl);
                        });

                        foreach (var st in subArray.Reverse())
                        {
                            if (st.IsAbstract || st.Block == null || !st.IsAccessibleFrom(apply.Source))
                            {
                                continue;
                            }

                            var obj      = new AsOp(apply.Object.Source, apply.Object, st);
                            var subBlock = CreateFlattenedVirtualApplyInDrawBlock(apply.Source, drawBlock, i, obj, st.Block);
                            var cond     = new IsOp(apply.Object.Source, apply.Object, st, compiler.Essentials.Bool);
                            var subIf    = new IfElse(subBlock.Source, cond, subBlock.DrawScope);

                            if (lastIf == null)
                            {
                                root   = subIf;
                                lastIf = subIf;
                            }
                            else
                            {
                                lastIf.OptionalElseBody = subIf;
                                lastIf = subIf;
                            }

                            drawBlock.Method.DrawBlocks.Insert(++baseIndex, subBlock);
                            TrySplitVirtualAppliesInDrawBlockRecursive(compiler, subBlock, ref baseIndex, drawScopes);
                        }
                    }

                    if (!dt.IsAbstract)
                    {
                        var baseBlock = CreateFlattenedVirtualApplyInDrawBlock(apply.Source, drawBlock, i, apply.Object, apply.Block);

                        if (lastIf == null)
                        {
                            root = baseBlock.DrawScope;
                        }
                        else
                        {
                            lastIf.OptionalElseBody = baseBlock.DrawScope;
                        }

                        drawBlock.Method.DrawBlocks.Insert(++baseIndex, baseBlock);
                        TrySplitVirtualAppliesInDrawBlockRecursive(compiler, baseBlock, ref baseIndex, drawScopes);
                    }

                    if (root != null)
                    {
                        drawBlock.DrawScope.Statements.Add(root);
                    }

                    drawScopes.Add(drawBlock.Method.DrawBlocks[drawBlockIndex].DrawScope);
                    drawBlock.Method.DrawBlocks.RemoveAt(drawBlockIndex);
                    drawBlockIndex += baseIndex - drawBlockIndex - 1;
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 12
0
        static void GenerateDrawCalls(Compiler compiler, Method initMethod, Method freeMethod, DrawBlock drawBlock, HashSet <Scope> drawScopes)
        {
            foreach (var drawable in drawBlock.Drawables)
            {
                new ShaderGenerator(compiler, drawable, initMethod.Body, freeMethod.Body, drawBlock.DrawScope).Generate();
                FixedArrayProcessor.Process(compiler.Pass, drawable.DrawState.VertexShader);
                FixedArrayProcessor.Process(compiler.Pass, drawable.DrawState.PixelShader);
                VariableInliner.Process(compiler.Pass, drawable.DrawState.VertexShader);
                VariableInliner.Process(compiler.Pass, drawable.DrawState.PixelShader);
            }

            foreach (var drawable in drawBlock.Drawables)
            {
                drawBlock.DrawScope.Statements.Add(new Draw(drawable.Source, drawable.DrawState));
                drawScopes.Add(drawBlock.DrawScope);
            }
        }