Root/include/ui.hhp

1#pypp 0
2#include <iris.hh>
3#include <devices.hh>
4
5template <unsigned I, unsigned O> //
6class 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

Archive Download this file

Branches:
master



interactive