mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-05 16:45:20 +02:00
117 lines
3.3 KiB
Plaintext
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
|