1 /++ 2 Copyright (C) 2012 Nick Sabalausky <http://semitwist.com/contact> 3 4 This program is free software. It comes without any warranty, to 5 the extent permitted by applicable law. You can redistribute it 6 and/or modify it under the terms of the Do What The Fuck You Want 7 To Public License, Version 2, as published by Sam Hocevar. See 8 http://www.wtfpl.net/ for more details. 9 10 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 Version 2, December 2004 12 13 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> 14 15 Everyone is permitted to copy and distribute verbatim or modified 16 copies of this license document, and changing it is allowed as long 17 as the name is changed. 18 19 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 20 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 21 22 0. You just DO WHAT THE FUCK YOU WANT TO. 23 +/ 24 25 /++ 26 Should work with DMD 2.059 and up 27 28 For more info on this, see: 29 http://semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration 30 +/ 31 module gfx.decl.sdlang.libInputVisitor; 32 33 import core.thread; 34 35 class InputVisitor(Obj, Elem) : Fiber 36 { 37 bool started = false; 38 Obj obj; 39 this(Obj obj) 40 { 41 this.obj = obj; 42 43 version(Windows) // Issue #1 44 { 45 import core.sys.windows.windows : SYSTEM_INFO, GetSystemInfo; 46 SYSTEM_INFO info; 47 GetSystemInfo(&info); 48 auto PAGESIZE = info.dwPageSize; 49 50 super(&run, PAGESIZE * 16); 51 } 52 else 53 super(&run); 54 } 55 56 this(Obj obj, size_t stackSize) 57 { 58 this.obj = obj; 59 super(&run, stackSize); 60 } 61 62 private void run() 63 { 64 obj.visit(this); 65 } 66 67 private void ensureStarted() 68 { 69 if(!started) 70 { 71 call(); 72 started = true; 73 } 74 } 75 76 // Member 'front' must be a function due to DMD Issue #5403 77 private Elem _front = Elem.init; // Default initing here avoids "Error: field _front must be initialized in constructor" 78 @property Elem front() 79 { 80 ensureStarted(); 81 return _front; 82 } 83 84 void popFront() 85 { 86 ensureStarted(); 87 call(); 88 } 89 90 @property bool empty() 91 { 92 ensureStarted(); 93 return state == Fiber.State.TERM; 94 } 95 96 void yield(Elem elem) 97 { 98 _front = elem; 99 Fiber.yield(); 100 } 101 } 102 103 template inputVisitor(Elem) 104 { 105 @property InputVisitor!(Obj, Elem) inputVisitor(Obj)(Obj obj) 106 { 107 return new InputVisitor!(Obj, Elem)(obj); 108 } 109 110 @property InputVisitor!(Obj, Elem) inputVisitor(Obj)(Obj obj, size_t stackSize) 111 { 112 return new InputVisitor!(Obj, Elem)(obj, stackSize); 113 } 114 }