kuro/node.c

134 lines
3.1 KiB
C

#include "dat.h"
#include "fns.h"
static Instruction init_instr = { INIT, nil };
void node_setup(Node* self, Handler* handlers, KuroMemory* memory) {
if (self) {
self->handlers = handlers;
self->memory = memory;
self->cpu = chancreate(sizeof(Instruction), 0);
self->status = chancreate(sizeof(WindowStatus), 0);
}
}
void node_loop(void* data) {
Node* self = (Node*)data;
Instruction x;
for (;;) {
print("waiting for instruction\n");
recv(self->cpu, &x);
print("got opcode: %d\n", x.opcode);
if (self->handlers[x.opcode]) {
(*(self->handlers[x.opcode]))(self, x.data);
print("finished executing handler for opcode %d\n", x.opcode);
switch(self->memory->status) {
case KURO_QUITS:
nbsend(self->status, 0);
threadexits(0);
default:
break;
}
flushimage(display, 1);
print("refreshed screen\n");
}
}
}
void node_execute(Node* self) {
threadcreate(node_loop, self, 1024);
}
Node* create_node(char* filename) {
initdraw(nil, nil, "kuro");
KuroMemory* self = (KuroMemory*)malloc(sizeof(KuroMemory));
Node* node = (Node*)malloc(sizeof(Node));
Handler* handlers = get_handlers();
node_setup(node, handlers, self);
self->img = allocimage(display, screen->r, screen->chan, 1, display->black);
self->screen = _screen;
if (filename) {
strcpy(self->filepath, filename);
}
/* node_execute runs the node on a separate thread */
node_execute(node);
send(node->cpu, (void*)&init_instr);
return node;
}
void supervise_node(Node* self) {
Mousectl* mctl;
Keyboardctl* kctl;
Mouse mouse;
int resize[2];
WindowStatus status;
Rune kbd;
if ((mctl = initmouse(nil, self->memory->img)) == nil) {
sysfatal("couldn't initialize mctl");
}
if ((kctl = initkeyboard(nil)) == nil) {
sysfatal("couldn't initialize kctl");
}
Alt alts[TOTAL_PORTS + 1] = {
{mctl->c, &mouse, CHANRCV},
{mctl->resizec, resize, CHANRCV},
{kctl->c, &kbd, CHANRCV},
{self->status, &status, CHANRCV},
{nil, nil, CHANEND}
};
for (;;) {
switch (alt(alts)) {
case PORT_MOUSE:
print("got a mouse event\n");
break;
case PORT_RESIZE:
/*if (getwindow(display, Refnone) < 0)
sysfatal("couldn't resize");*/
print("got a resize event\n");
break;
case PORT_KBD:
print("got a keypress\n");
break;
case PORT_STATUS:
switch(status) {
case KURO_QUITS:
print("VM died - let's clean up the data\n");
goto cleanup;
default:
break;
}
break;
}
}
cleanup:
node_cleanup(self);
}
void node_cleanup(Node* self) {
if (self) {
memory_cleanup(self->memory);
chanfree(self->cpu);
chanfree(self->status);
/* TODO: send message on self->fd to tell the server to remove us from NodeTable and filetree */
/* handlers array is shared between all the nodes */
free(self);
}
}
void memory_cleanup(KuroMemory* self) {
if (self) {
/* do we need to free the img and screen? */
}
}