#pypp 0 #include #include template // class UI: struct in_base: UI *ui unsigned my_index void (*handle) (in_base *self, void (*cb)(unsigned)) void (*send) (in_base *self, Iris::Cap c) in_base () : ui (NULL), my_index (0), handle (NULL), send (NULL): struct out_base: UI *ui unsigned my_index void (*send) (out_base *self, Iris::Cap c) out_base () : ui (NULL), my_index (0), send (NULL): public: void init (Iris::Cap my_cap): Iris::my_parent.provide_capability (my_cap) template // class in : public in_base: friend class UI _T my_data static void send_impl (in_base *self, Iris::Cap c): c.invoke (self->my_index | Iris::UI::INPUT, reinterpret_cast *> (self)->my_data) static void handle_impl (in_base *self, void (*cb)(unsigned)): in *me = reinterpret_cast (self) if me->my_data == Iris::recv.data[1].l: return me->my_data = Iris::recv.data[1].l cb (me->my_index) public: void init (): this->send = &send_impl this->handle = &handle_impl operator _T () const: return my_data class in_event : public in_base: friend class UI static void send_impl (in_base *self, Iris::Cap c): c.invoke (self->my_index | Iris::UI::INPUT) static void handle_impl (in_base *self, void (*cb)(unsigned)): cb (self->my_index) public: void init (): this->send = &send_impl this->handle = &handle_impl template // class out : public out_base: friend class UI _T my_data static void send_impl (out_base *self, Iris::Cap c): c.invoke (self->my_index, reinterpret_cast *> (self)->my_data) public: void init (): this->send = &send_impl out <_T> &operator= (_T const &t): if !this->ui || my_data == t: return *this my_data = t send_impl (this, this->ui->cap) return *this operator _T () const: return my_data class out_event : public out_base: friend class UI public: static void send_impl (out_base *self, Iris::Cap c): // Don't send an event. This is only for listing the state. void operator() (): if !this->ui: return this->ui->cap.invoke (this->my_index) void init (): this->send = &send_impl void add_in (in_base *obj, unsigned code): ins[code] = obj obj->ui = this obj->my_index = code void add_out (out_base *obj, unsigned code): outs[code] = obj obj->ui = this obj->my_index = code bool event (void (*cb)(unsigned)): switch Iris::recv.data[0].l: case Iris::UI::EXIT: Iris::recv.reply.invoke () return false case Iris::UI::GET_STATE: if cap.code != CAP_NONE: Iris::free_cap (cap) cap = Iris::get_arg () Iris::recv.reply.invoke () for unsigned i = 0; i < I; ++i: ins[i]->send (ins[i], cap) for unsigned i = 0; i < O; ++i: outs[i]->send (outs[i], cap) break case Iris::UI::EVENT: Iris::Cap r = Iris::get_reply () if Iris::recv.data[0].h >= I: Iris::panic (Iris::recv.data[0].h, "invalid input requested by ui") ins[Iris::recv.data[0].h]->handle (ins[Iris::recv.data[0].h], cb) r.invoke () Iris::free_cap (r) break default: Iris::panic (Iris::recv.data[0].l, "invalid request for ui") return true private: in_base *ins[I] out_base *outs[O] Iris::Cap cap