aboutsummaryrefslogtreecommitdiffstats
path: root/serve
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-18 20:54:10 +0100
committereunhhu <[email protected]>2026-10-18 20:54:10 +0100
commitda0d7514b058f1baa99a8bcc8f9e23b43cac12de (patch)
tree688106ea656946bd74f36259c2dd2316b9a429d8 /serve
parent936c08e3424c606855051ee86f25a7df0f162c62 (diff)
downloadpure-da0d7514b058f1baa99a8bcc8f9e23b43cac12de.tar.gz
pure-da0d7514b058f1baa99a8bcc8f9e23b43cac12de.zip
Module format v7, 027's 4d: every input a message: a module's inputs are messages, outputs and arguments (kinds 1 to 3), a message bound to what makes it (PureBinding: a key's press or its release, a text input, a timer, a frame, a pointing at a table), each binding's fields fixed (none; one text; one number, dt; one u32, the item's position, the table its view), one frame input at most; a handler's event its input's number; no DT or TEXT_INPUT (97 opcodes now 95, FIELD reads dt and the text), pure_app_input, frame, tick, text and point, pure_module_position, PureEdge or an app's ticks: every event is pure_app_message, saved after it unless deferred; pure-run sends each command's message to the input bound so (a release or a frame no input takes still an event, clearing the fault, so the workbench parity holds) and defers a stored app's saves past frames as before; pure-serve posts a press with its key's release, refuses timers, frames and pointings (no_input) and ticks timers as messages; holes closed: the tier found a handler's input by the old numbering, reading a message's number field as another input's (aup's numbers caught it), and serve's replies_borrow did too; module-probe presses as messages; unit tests: the test modules' builder (expand) writes the old shapes as bound messages, pointing over a pointing input and its table, stored frames deferred as a host defers them, a press's handler refused a FIELD; counts: b35 against b34 with batches BFS +0.03%, the rest within 0.001%, without batches BFS +0.12%, join +0.01%; the bank's queries (s34 on the 4c aup's module, s35 on 4d's, six each in turns) field -0.23%, found -0.14%, large -0.12%, in_credit +0.11%, the rest within 0.06%; 008 and 027
Diffstat (limited to 'serve')
-rw-r--r--serve/serve.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/serve/serve.c b/serve/serve.c
index 500f470..81479ba 100644
--- a/serve/serve.c
+++ b/serve/serve.c
@@ -900,10 +900,10 @@ static const char *resolve(Connection *c, char *query, Route *route, int *status
return NULL;
}
int found = route->kind == ROUTE_VIEW ? pure_module_view(m, c->key) : pure_module_input(m, c->key);
- /* An output is the app's to send and a timer ticks by itself: neither is posted. */
+ /* An output is the app's to send, and a host makes a tick, a frame and a pointing: none is posted. */
if (found >= 0 && route->kind == ROUTE_INPUT &&
- (m->input[found].kind == PURE_KIND_OUTPUT || m->input[found].kind == PURE_KIND_TIMER ||
- m->input[found].kind == PURE_KIND_ARGUMENTS)) found = -1;
+ (m->input[found].kind != PURE_KIND_MESSAGE || m->input[found].binding == PURE_BIND_TIMER ||
+ m->input[found].binding == PURE_BIND_FRAME || m->input[found].binding == PURE_BIND_POINT)) found = -1;
if (found < 0) return route->kind == ROUTE_VIEW ? "no_view" : "no_input";
*status = 400;
route->target = (uint32_t)found;
@@ -914,7 +914,7 @@ static const char *resolve(Connection *c, char *query, Route *route, int *status
if (*c->source && !message) return "delivery";
if (!app->owned) c->source[0] = 0; /* an app without states or outputs applies it as a message */
if (shape) {
- /* A body is a text input's text, a message's one variable field (rows
+ /* A body is a message's one variable field (a text input's text; rows
* in their list's stored form), or a JSON object of a message's fields
* (two variable fields need one). */
unsigned variables = 0;
@@ -923,8 +923,7 @@ static const char *resolve(Connection *c, char *query, Route *route, int *status
m->field[shape->field_start + f].type == PURE_FIELD_TEXT ||
m->field[shape->field_start + f].type == PURE_FIELD_ROWS;
if (c->json && !message) return "json";
- if (!c->json && (variables > 1 || (c->body_size && shape->kind == PURE_KIND_KEY) ||
- (c->body_size && message && !variables))) return variables > 1 ? "json" : "body";
+ if (!c->json && (variables > 1 || (c->body_size && !variables))) return variables > 1 ? "json" : "body";
c->input = (uint32_t)found;
c->field_bytes = message ? shape->prefix : 0;
}
@@ -1633,11 +1632,12 @@ static PureResult apply_input(PureApp *app, const Route *route, const PureEffect
size_t lead = 4 + (header & DELIVERED ? DELIVERY : 0), table = header & PLACED ? 8 * (size_t)shape->field_count : 0;
PureSpan payload = {effect->value.data + lead + batch * table, header & ~(PLACED | DELIVERED)};
PureResult status;
- if (shape->kind == PURE_KIND_TEXT) {
- status = pure_app_text(app, route->target, payload);
- } else if (shape->kind == PURE_KIND_KEY) {
- status = pure_app_input(app, route->target, PURE_EDGE_DOWN);
- if (status == PURE_OK) status = pure_app_input(app, route->target, PURE_EDGE_UP);
+ if (shape->binding == PURE_BIND_PRESS) { /* a key pressed: its press, and its release when a message takes it */
+ const PureModule *m = app->module;
+ status = pure_app_message(app, route->target, (PureSpan){0});
+ for (uint32_t i = 0; status == PURE_OK && i < m->inputs; ++i)
+ if (m->input[i].binding == PURE_BIND_RELEASE && !strcmp(m->input_keys[i], m->input_keys[route->target]))
+ status = pure_app_message(app, i, (PureSpan){0});
} else {
uint32_t placed[2 * PURE_MODULE_FIELDS];
for (size_t i = 0; table && i < 2 * (size_t)shape->field_count; ++i)
@@ -2114,11 +2114,11 @@ static long run_timers(Executor *ex) {
uint64_t now = now_ms(), soonest = UINT64_MAX;
bool ticked = false;
for (uint32_t i = 0; i < m->inputs; ++i) {
- if (m->input[i].kind != PURE_KIND_TIMER) continue;
+ if (m->input[i].binding != PURE_BIND_TIMER) continue;
if (!ex->next[i]) ex->next[i] = now + m->input[i].period; /* the first period starts now */
if (ex->next[i] <= now) {
ex->app.now = wall_ms();
- if (pure_app_tick(&ex->app, i) == PURE_OK) ++ex->ticks;
+ if (pure_app_message(&ex->app, i, (PureSpan){0}) == PURE_OK) ++ex->ticks;
ticked = true;
ex->next[i] = now + m->input[i].period;
}
@@ -3138,7 +3138,7 @@ static void surface_release(PureSurfaceHost *s, PureSnapshot *snapshot) {
static PureResult surface_event(PureSurfaceHost *s, uint32_t input, PureSpan text) {
Owner *owner = s->owner;
const PureModule *m = owner->executor.module;
- if (input >= m->inputs || (m->input[input].kind != PURE_KIND_KEY && m->input[input].kind != PURE_KIND_TEXT) ||
+ if (input >= m->inputs || (m->input[input].binding != PURE_BIND_PRESS && m->input[input].binding != PURE_BIND_TEXT) ||
(text.size && !text.data))
return PURE_INVALID;
if (text.size > PURE_OBJECT_LIMIT) return PURE_LIMIT;
@@ -3167,14 +3167,14 @@ static PureResult surface_event(PureSurfaceHost *s, uint32_t input, PureSpan tex
static PureResult surface_press(PureSurfaceHost *s, uint32_t input) {
return input < s->owner->executor.module->inputs &&
- s->owner->executor.module->input[input].kind == PURE_KIND_KEY
+ s->owner->executor.module->input[input].binding == PURE_BIND_PRESS
? surface_event(s, input, (PureSpan){0})
: PURE_INVALID;
}
static PureResult surface_type(PureSurfaceHost *s, uint32_t input, PureSpan text) {
return input < s->owner->executor.module->inputs &&
- s->owner->executor.module->input[input].kind == PURE_KIND_TEXT
+ s->owner->executor.module->input[input].binding == PURE_BIND_TEXT
? surface_event(s, input, text)
: PURE_INVALID;
}
@@ -3216,7 +3216,7 @@ static bool start_surface(PureSurfaceHost *s, Owner *owner, int argc, char **arg
* served by PUT or POST may reply only a field of its message. */
static bool replies_borrow(const PureModule *m, uint32_t input) {
for (uint32_t h = 0; h < m->handlers; ++h) {
- if (m->handler[h].event != 1 + 2 * input) continue;
+ if (m->handler[h].event != input) continue;
const PureBlock *code = &m->handler[h].code;
/* A field replied as it is, or a text field as its bytes. */
for (uint32_t pc = code->start; pc < code->start + code->length; ++pc) {