digitalmars.D - How to switch context from fiber to original fiber?
- Patrick Jeeves (73/73) Nov 21 2014 So I've been using an event range rather than an event loop or
So I've been using an event range rather than an event loop or event/listener system; because I realized I could process events more effectively using a recursive descent parser on them. So I made this class to strip the events into different ranges and send them to different parsers: auto demultiplex(alias attrFunc, string functional, Range)(Range r) { alias attr = std.functional.unaryFun!(attrFunc); alias T = ElementType!(Range); struct SlaveRange { private T** _front; private Fiber _fiber; this(T ** it) { _front = it; _fiber = Fiber.getThis(); } property bool empty() const { return *_front is null; } property T front() const { return *(*_front); } void popFront() { _fiber.call(); } } struct MasterRange { private SlaveRange _slave; private Range _input; private T _cur; private T * _front; private Fiber _fiber; private void run() { mixin("_slave." ~ functional ~ ";"); } private void call() { if(_fiber.state != Fiber.State.TERM) _fiber.call(); } this(Range ins) { _input = ins; _fiber = new Fiber(&run); _slave = &_front; popFront(); _front = &_cur; } property T front() const { return *_front; } property bool empty() const { return _front is null; } void popFront() { while(!_input.empty) { _cur = _input.front; _input.popFront(); final switch(attr(_cur)) { case -1: break; case 0: return; case 1: call(); break; case 2: call(); return; } } _front = null; } } return MasterRange(r); } the problem is that when the SlaveRange is constructed it needs to know the current fiber, but if it isn't called from a fiber then it returns null and can't switch back. And I can't use yeild because I don't want to return to the calling fiber, that doesn't help me.
Nov 21 2014