|
D Paste by downs
Description: test27.d; full
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | module test27; import tools.base; struct QdEvent { enum Type { MouseMoved, MouseClicked, MousePushed, MouseReleased } Type type; pt pos; int button; // 0 unless appropriate } alias Stuple!() Nothing; // sadly, void is a keyword Stuple!() nothing; Nothing[void delegate(QdEvent)] listeners; template toDelegate(T...) { typeof((T t) { C c; return c(t); }) toDelegate(C)(C callable) { struct Wrapper { C callable; typeof(function{ T t; return callable(t); }()) call(T t) { return callable(t); } } auto res = new Wrapper; res.callable = callable; return &res.call; } } void registerCallback(C)(C callable) { listeners[toDelegate!(QdEvent)(callable)] = nothing; } private void dispatchEvent(QdEvent q) { foreach (key, bogus; listeners) key(q); } // void events(void delegate(ushort, bool) key=null, void delegate(int, int, ubyte, int) mouse=null, void delegate() quit=null) void checkEvents() { events((ushort u) { }, (int x, int y, ubyte button, int dir) { switch (dir) { case 0: dispatchEvent = QdEvent(QdEvent.Type.MouseMoved, pt(x, y), button); break; case 1: dispatchEvent = QdEvent(QdEvent.Type.MousePushed, pt(x, y), button); break; case -1: dispatchEvent = QdEvent(QdEvent.Type.MouseReleased, pt(x, y), button); break; } }, { throw new Exception("Quit"); }); } struct CondSliceFunctorPre(T) { T sup; CondSliceFunctor!(T, U, V) opSlice(U, V)(U u, V v) { CondSliceFunctor!(T, U, V) res; res.sup = sup; res.u = u; res.v = v; return res; } } CondSliceFunctorPre!(T) condslice(T)(T t) { return CondSliceFunctorPre!(T)(t); } template isCallable(T, U) { static if (is(typeof({ T foo; U param; foo(param); }))) const bool isCallable = true; else const bool isCallable = true; } struct CondSliceFunctor(T, U, V) { T sup; U u; V v; bool inRange; void opCall(W)(W w) { logln("cond slice with ", w, ", inRange ", inRange, ", and ", u(w)); static assert(isCallable!(T, W), "Cond-Slice problem: can't call "~T.stringof~" with "~W.stringof~"! "); static assert(isCallable!(U, W), "Cond-Slice problem: can't call start cond "~U.stringof~" with "~W.stringof~"! "); static assert(isCallable!(V, W), "Cond-Slice problem: can't call end cond "~V.stringof~" with "~W.stringof~"! "); if (inRange) { sup(w); if (v(w)) { inRange = false; } } else if (u(w)) { inRange = true; sup(w); } } } import qd; void main() { screen(640, 480); pt pos; alias ex!("v -> f -> f.type == v") TypeCheck; alias ex!("a, b -> x -> a(x) && b(x)") And; alias ex!("a -> b -> b.pos in a()") LazyIn; registerCallback( condslice((QdEvent qe) { if (qe.type == QdEvent.Type.MouseMoved) { pos = qe.pos; } })[ And(TypeCheck(QdEvent.Type.MousePushed), LazyIn({ return Area(pos - pt(10), pt(20)); })) .. TypeCheck(QdEvent.Type.MouseReleased) ] ); while (true) { cls; circle(pos.x, pos.y, 10); flip; checkEvents; } } |