1 module test_fiber; 2 3 import core.thread.fiber; 4 import std.stdio; 5 import std.algorithm; 6 7 import auxil.model; 8 9 import test_data; 10 import common; 11 12 struct MyVisitor 13 { 14 import auxil.model : TreePath; 15 16 enum treePathNGEnabled = true; 17 enum treePathEnabled = false; 18 enum sizeEnabled = false; 19 20 TreePath tree_path; 21 22 TreePath[] log; 23 24 TreePath path; 25 private bool _complete; 26 27 bool complete() @trusted @nogc 28 { 29 return _complete; 30 } 31 32 void enterTree(alias order, Data, Model)(auto ref const(Data) data, ref Model model) 33 { 34 } 35 36 auto enterNode(alias order, Data, Model)(ref const(Data) data, ref Model model) 37 { 38 log ~= tree_path; 39 Fiber.yield(); 40 { 41 _complete = !path.value.empty && tree_path.value[] == path.value[]; 42 } 43 44 return false; 45 } 46 47 void leaveNode(alias order, Data, Model)(ref const(Data) data, ref Model model) 48 { 49 Fiber.yield(); 50 } 51 52 void processLeaf(alias order, Data, Model)(ref const(Data) data, ref Model model) 53 { 54 55 log ~= tree_path; 56 Fiber.yield(); 57 { 58 _complete = !path.value.empty && tree_path.value[] == path.value[]; 59 } 60 } 61 } 62 63 // a fiber traverses to the specific tree path in forward direction 64 void testRunningFiberInLoop() 65 { 66 auto model = makeModel(m.a2); 67 68 MyVisitor visitor; 69 70 scope fiberVisitor = new Fiber(() 71 { 72 model.visitForward(m.a2, visitor); 73 }); 74 75 TreePath[] fiberLog; 76 foreach(_; 0..3) 77 { 78 fiberLog = null; 79 visitor.log = null; 80 visitor.path.value = [1, 0]; 81 visitor.tree_path.value.clear; 82 visitor._complete = false; 83 fiberVisitor.reset; 84 while(fiberVisitor.state != Fiber.State.TERM) 85 { 86 fiberVisitor.call(); 87 if (!visitor.complete) 88 { 89 fiberLog ~= visitor.tree_path; 90 } 91 } 92 93 fiberLog.each!writeln; 94 assert(visitor.log.equal(fiberLog)); 95 96 writeln("\n---"); 97 writeln(visitor.log); 98 assert(visitor.log.equal([ 99 [], // a2 100 [1], // a2.b 101 // a2.b.f skipped 102 [1, 0], // a2.b.i 103 ])); 104 } 105 } 106 107 // a fiber traverses to the specific tree path in forward direction 108 void testFiberRange() 109 { 110 auto model = makeModel(m.a2); 111 112 MyVisitor visitor; 113 114 TreePath[] fiberLog; 115 { 116 fiberLog = null; 117 visitor.log = null; 118 visitor.path.value = [1, 0]; 119 visitor.tree_path.value.clear; 120 visitor._complete = false; 121 auto r = visitor.makeRange(() 122 { 123 model.visitForward(m.a2, visitor); 124 }); 125 r.each!((ref a)=>writeln(a)); 126 writeln("---"); 127 visitor = MyVisitor(); 128 visitor.path.value = [1, 0]; 129 r = visitor.makeRange(() 130 { 131 model.visitForward(m.a2, visitor); 132 }); 133 r.each!((ref a)=>writeln(a)); 134 } 135 }