AstBlockVisitor.cs
1 using System; 2 using System.Collections.Generic; 3 4 using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; 5 6 namespace Ryujinx.Graphics.Shader.StructuredIr 7 { 8 class AstBlockVisitor 9 { 10 public AstBlock Block { get; private set; } 11 12 public class BlockVisitationEventArgs : EventArgs 13 { 14 public AstBlock Block { get; } 15 16 public BlockVisitationEventArgs(AstBlock block) 17 { 18 Block = block; 19 } 20 } 21 22 public event EventHandler<BlockVisitationEventArgs> BlockEntered; 23 public event EventHandler<BlockVisitationEventArgs> BlockLeft; 24 25 public AstBlockVisitor(AstBlock mainBlock) 26 { 27 Block = mainBlock; 28 } 29 30 public IEnumerable<IAstNode> Visit() 31 { 32 IAstNode node = Block.First; 33 34 while (node != null) 35 { 36 // We reached a child block, visit the nodes inside. 37 while (node is AstBlock childBlock) 38 { 39 Block = childBlock; 40 41 node = childBlock.First; 42 43 BlockEntered?.Invoke(this, new BlockVisitationEventArgs(Block)); 44 } 45 46 // Node may be null, if the block is empty. 47 if (node != null) 48 { 49 IAstNode next = Next(node); 50 51 yield return node; 52 53 node = next; 54 } 55 56 // We reached the end of the list, go up on tree to the parent blocks. 57 while (node == null && Block.Type != AstBlockType.Main) 58 { 59 BlockLeft?.Invoke(this, new BlockVisitationEventArgs(Block)); 60 61 node = Next(Block); 62 63 Block = Block.Parent; 64 } 65 } 66 } 67 } 68 }