1 module fluid.future.branch_action; 2 3 import fluid.node; 4 import fluid.tree; 5 import fluid.types; 6 7 @safe: 8 9 abstract class BranchAction : TreeAction { 10 11 private { 12 13 /// Balance is incremented when entering a node, and decremented when leaving. 14 /// If the balance is negative, the action stops. 15 int _balance; 16 17 } 18 19 /// A branch action can only hook to draw calls of specific nodes. It cannot bind into these hooks. 20 final override void beforeTree(Node, Rectangle) { } 21 22 /// ditto 23 final override void beforeResize(Node, Vector2) { } 24 25 /// ditto 26 final override void afterTree() { 27 stop; 28 } 29 30 /// ditto 31 final override void afterInput(ref bool) { } 32 33 /// Branch action excludes the start node from results. 34 /// Returns: 35 /// True only if the node is a child of the `startNode`; always true if there isn't one set. 36 override bool filterBeforeDraw(Node node) @trusted { 37 38 _balance++; 39 40 // No start node 41 if (startNode is null) { 42 return true; 43 } 44 45 const filter = super.filterBeforeDraw(node); 46 47 // Skip the start node 48 if (node == startNode) { 49 return false; 50 } 51 52 return filter; 53 54 55 } 56 57 /// Branch action excludes the start node from results. 58 /// Returns: 59 /// True only if the node is a child of the `startNode`; always true if there isn't one set. 60 override bool filterAfterDraw(Node node) @trusted { 61 62 _balance--; 63 64 // Stop if balance is negative 65 if (_balance < 0) { 66 stop; 67 return false; 68 } 69 70 // No start node 71 if (startNode is null) { 72 return true; 73 } 74 75 const filter = super.filterAfterDraw(node); 76 77 // Stop the action when exiting the start node 78 if (node == startNode) { 79 stop; 80 return false; 81 } 82 83 return filter; 84 85 } 86 87 override void stopped() { 88 89 super.stopped(); 90 _balance = 0; 91 92 } 93 94 }