#ifndef GHOST_BASIC_H #define GHOST_BASIC_H template class Bounce { public: Link > link; Bounce(T& o) : link(o, this, &Bounce::signal) {} void signal() { link.signal(); } }; template class Stop { public: Link > link; Stop(T& o) : link(o, this, &Stop::signal) {} void signal() {} }; template class Tee { public: Link > in, out0, out1; enum { empty, two, one } state; Tee(T& i, T& o0, T& o1) : in(i, this, &Tee::signal_in), out0(o0, this, &Tee::signal_out), out1(o1, this, &Tee::signal_out), state(empty) {} void signal_in() { assert(state == empty); out0.o = out1.o = in.o; state = two; out0.signal(); out1.signal(); } void signal_out() { assert(state == one || state == two); if (state == two) { state = one; } else { state = empty; in.signal(); } } }; template class Merge { Link > in0, in1, out; enum { clear, sent0, sent1, sent0got1, sent1got0 } state; Merge(T& i0, T& i1, T& o) : in0(i0, this, &Merge::_in0), in1(i1, this, &Merge::_in1), out(o, this, &Merge::_out), state(clear) {} void _in0() { assert(state == clear || state); out.o = in.o; state = sent0; out.signal(); } void _out() { } }; #endif