Root/
| 1 | #pypp 0 |
| 2 | #include <iris.hh> |
| 3 | #include <devices.hh> |
| 4 | |
| 5 | template <unsigned I, unsigned O> // |
| 6 | class UI: |
| 7 | struct in_base: |
| 8 | UI <I, O> *ui |
| 9 | unsigned my_index |
| 10 | void (*handle) (in_base *self, void (*cb)(unsigned)) |
| 11 | void (*send) (in_base *self, Iris::Cap c) |
| 12 | in_base () : ui (NULL), my_index (0), handle (NULL), send (NULL): |
| 13 | struct out_base: |
| 14 | UI <I, O> *ui |
| 15 | unsigned my_index |
| 16 | void (*send) (out_base *self, Iris::Cap c) |
| 17 | out_base () : ui (NULL), my_index (0), send (NULL): |
| 18 | |
| 19 | public: |
| 20 | |
| 21 | void init (Iris::Cap my_cap): |
| 22 | Iris::my_parent.provide_capability <Iris::UI> (my_cap) |
| 23 | template <typename _T> // |
| 24 | class in : public in_base: |
| 25 | friend class UI <I, O> |
| 26 | _T my_data |
| 27 | static void send_impl (in_base *self, Iris::Cap c): |
| 28 | c.invoke (self->my_index | Iris::UI::INPUT, reinterpret_cast <in <_T> *> (self)->my_data) |
| 29 | static void handle_impl (in_base *self, void (*cb)(unsigned)): |
| 30 | in *me = reinterpret_cast <in *> (self) |
| 31 | if me->my_data == Iris::recv.data[1].l: |
| 32 | return |
| 33 | me->my_data = Iris::recv.data[1].l |
| 34 | cb (me->my_index) |
| 35 | public: |
| 36 | void init (): |
| 37 | this->send = &send_impl |
| 38 | this->handle = &handle_impl |
| 39 | operator _T () const: |
| 40 | return my_data |
| 41 | class in_event : public in_base: |
| 42 | friend class UI <I, O> |
| 43 | static void send_impl (in_base *self, Iris::Cap c): |
| 44 | c.invoke (self->my_index | Iris::UI::INPUT) |
| 45 | static void handle_impl (in_base *self, void (*cb)(unsigned)): |
| 46 | cb (self->my_index) |
| 47 | public: |
| 48 | void init (): |
| 49 | this->send = &send_impl |
| 50 | this->handle = &handle_impl |
| 51 | template <typename _T> // |
| 52 | class out : public out_base: |
| 53 | friend class UI <I, O> |
| 54 | _T my_data |
| 55 | static void send_impl (out_base *self, Iris::Cap c): |
| 56 | c.invoke (self->my_index, reinterpret_cast <out <_T> *> (self)->my_data) |
| 57 | public: |
| 58 | void init (): |
| 59 | this->send = &send_impl |
| 60 | out <_T> &operator= (_T const &t): |
| 61 | if !this->ui || my_data == t: |
| 62 | return *this |
| 63 | my_data = t |
| 64 | send_impl (this, this->ui->cap) |
| 65 | return *this |
| 66 | operator _T () const: |
| 67 | return my_data |
| 68 | class out_event : public out_base: |
| 69 | friend class UI <I, O> |
| 70 | public: |
| 71 | static void send_impl (out_base *self, Iris::Cap c): |
| 72 | // Don't send an event. This is only for listing the state. |
| 73 | void operator() (): |
| 74 | if !this->ui: |
| 75 | return |
| 76 | this->ui->cap.invoke (this->my_index) |
| 77 | void init (): |
| 78 | this->send = &send_impl |
| 79 | void add_in (in_base *obj, unsigned code): |
| 80 | ins[code] = obj |
| 81 | obj->ui = this |
| 82 | obj->my_index = code |
| 83 | void add_out (out_base *obj, unsigned code): |
| 84 | outs[code] = obj |
| 85 | obj->ui = this |
| 86 | obj->my_index = code |
| 87 | bool event (void (*cb)(unsigned)): |
| 88 | switch Iris::recv.data[0].l: |
| 89 | case Iris::UI::EXIT: |
| 90 | Iris::recv.reply.invoke () |
| 91 | return false |
| 92 | case Iris::UI::GET_STATE: |
| 93 | if cap.code != CAP_NONE: |
| 94 | Iris::free_cap (cap) |
| 95 | cap = Iris::get_arg () |
| 96 | Iris::recv.reply.invoke () |
| 97 | for unsigned i = 0; i < I; ++i: |
| 98 | ins[i]->send (ins[i], cap) |
| 99 | for unsigned i = 0; i < O; ++i: |
| 100 | outs[i]->send (outs[i], cap) |
| 101 | break |
| 102 | case Iris::UI::EVENT: |
| 103 | Iris::Cap r = Iris::get_reply () |
| 104 | if Iris::recv.data[0].h >= I: |
| 105 | Iris::panic (Iris::recv.data[0].h, "invalid input requested by ui") |
| 106 | ins[Iris::recv.data[0].h]->handle (ins[Iris::recv.data[0].h], cb) |
| 107 | r.invoke () |
| 108 | Iris::free_cap (r) |
| 109 | break |
| 110 | default: |
| 111 | Iris::panic (Iris::recv.data[0].l, "invalid request for ui") |
| 112 | return true |
| 113 | private: |
| 114 | in_base *ins[I] |
| 115 | out_base *outs[O] |
| 116 | Iris::Cap cap |
| 117 |
Branches:
master
