1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-11-16 18:37:10 +02:00
iris/include/ui.hhp
2013-05-14 18:30:50 -04:00

117 lines
3.3 KiB
Plaintext

#pypp 0
#include <iris.hh>
#include <devices.hh>
template <unsigned I, unsigned O> //
class UI:
struct in_base:
UI <I, O> *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 <I, O> *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 <Iris::UI> (my_cap)
template <typename _T> //
class in : public in_base:
friend class UI <I, O>
_T my_data
static void send_impl (in_base *self, Iris::Cap c):
c.invoke (self->my_index | Iris::UI::INPUT, reinterpret_cast <in <_T> *> (self)->my_data)
static void handle_impl (in_base *self, void (*cb)(unsigned)):
in *me = reinterpret_cast <in *> (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 <I, O>
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 <typename _T> //
class out : public out_base:
friend class UI <I, O>
_T my_data
static void send_impl (out_base *self, Iris::Cap c):
c.invoke (self->my_index, reinterpret_cast <out <_T> *> (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 <I, O>
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