/ src / Ryujinx.Graphics.Shader / StructuredIr / AstBlockVisitor.cs
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  }