2024-01-22 07:50:23 +00:00
|
|
|
#include "dat.h"
|
|
|
|
#include "fns.h"
|
|
|
|
|
2024-02-02 05:57:26 +00:00
|
|
|
static Instruction init_instr = { INIT, nil };
|
2024-01-22 07:50:23 +00:00
|
|
|
|
2024-01-27 05:39:39 +00:00
|
|
|
void node_setup(Node* self, Handler* handlers, KuroMemory* memory) {
|
2024-01-22 07:50:23 +00:00
|
|
|
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 (;;) {
|
2024-02-02 05:57:26 +00:00
|
|
|
print("waiting for instruction\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
recv(self->cpu, &x);
|
2024-02-02 05:57:26 +00:00
|
|
|
print("got opcode: %d\n", x.opcode);
|
|
|
|
|
2024-01-22 07:50:23 +00:00
|
|
|
if (self->handlers[x.opcode]) {
|
|
|
|
(*(self->handlers[x.opcode]))(self, x.data);
|
2024-02-02 05:57:26 +00:00
|
|
|
print("finished executing handler for opcode %d\n", x.opcode);
|
2024-01-22 07:50:23 +00:00
|
|
|
switch(self->memory->status) {
|
|
|
|
case KURO_QUITS:
|
2024-02-02 05:57:26 +00:00
|
|
|
nbsend(self->status, 0);
|
2024-01-22 07:50:23 +00:00
|
|
|
threadexits(0);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2024-02-02 05:57:26 +00:00
|
|
|
flushimage(display, 1);
|
|
|
|
print("refreshed screen\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void node_execute(Node* self) {
|
|
|
|
threadcreate(node_loop, self, 1024);
|
|
|
|
}
|
|
|
|
|
2024-01-27 05:39:39 +00:00
|
|
|
Node* create_node(char* filename) {
|
2024-01-22 07:50:23 +00:00
|
|
|
|
|
|
|
initdraw(nil, nil, "kuro");
|
|
|
|
|
|
|
|
KuroMemory* self = (KuroMemory*)malloc(sizeof(KuroMemory));
|
|
|
|
Node* node = (Node*)malloc(sizeof(Node));
|
2024-02-02 05:57:26 +00:00
|
|
|
Handler* handlers = get_handlers();
|
2024-01-22 07:50:23 +00:00
|
|
|
|
2024-01-27 05:39:39 +00:00
|
|
|
node_setup(node, handlers, self);
|
2024-01-22 07:50:23 +00:00
|
|
|
|
2024-02-02 05:57:26 +00:00
|
|
|
self->img = allocimage(display, screen->r, screen->chan, 1, display->black);
|
2024-01-22 07:50:23 +00:00
|
|
|
self->screen = _screen;
|
2024-01-27 05:39:39 +00:00
|
|
|
if (filename) {
|
|
|
|
strcpy(self->filepath, filename);
|
|
|
|
}
|
2024-01-22 07:50:23 +00:00
|
|
|
|
|
|
|
/* node_execute runs the node on a separate thread */
|
|
|
|
node_execute(node);
|
2024-02-02 05:57:26 +00:00
|
|
|
|
|
|
|
send(node->cpu, (void*)&init_instr);
|
2024-01-22 07:50:23 +00:00
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
void supervise_node(Node* self) {
|
|
|
|
|
|
|
|
Mousectl* mctl;
|
|
|
|
Keyboardctl* kctl;
|
|
|
|
Mouse mouse;
|
|
|
|
int resize[2];
|
|
|
|
WindowStatus status;
|
|
|
|
Rune kbd;
|
|
|
|
|
2024-01-31 05:53:42 +00:00
|
|
|
if ((mctl = initmouse(nil, self->memory->img)) == nil) {
|
2024-01-22 07:50:23 +00:00
|
|
|
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:
|
2024-01-31 05:53:42 +00:00
|
|
|
print("got a mouse event\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
break;
|
|
|
|
case PORT_RESIZE:
|
2024-01-27 05:39:39 +00:00
|
|
|
/*if (getwindow(display, Refnone) < 0)
|
|
|
|
sysfatal("couldn't resize");*/
|
2024-01-31 05:53:42 +00:00
|
|
|
print("got a resize event\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
break;
|
|
|
|
case PORT_KBD:
|
2024-01-31 05:53:42 +00:00
|
|
|
print("got a keypress\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
break;
|
|
|
|
case PORT_STATUS:
|
|
|
|
switch(status) {
|
|
|
|
case KURO_QUITS:
|
2024-01-31 05:53:42 +00:00
|
|
|
print("VM died - let's clean up the data\n");
|
2024-01-22 07:50:23 +00:00
|
|
|
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? */
|
|
|
|
}
|
2024-01-27 05:39:39 +00:00
|
|
|
}
|