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()); }
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)); }
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); }
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); }
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); }
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); } } }
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); }
public static IPlayable Draw(Controller c, IPlayable cardToDraw = null) { return(DrawBlock.Invoke(c, cardToDraw)); }
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(); } } }
public Expression AddProgram(DrawBlock block, Expression program) { return(AddCached("Shader", () => program, block.Method.DeclaringType.UnoName, block)); }
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); }
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); } }