AstBlockVisitor.cs 1.8 KB

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