Initial LinuxCNC WebAssembly workspace snapshot

This commit is contained in:
2026-08-20 18:21:15 +08:00
commit 5dd614c335
92 changed files with 200203 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
#include "sim_protocol.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
typedef struct {
uint32_t state;
uint32_t last_seq;
uint32_t tick;
} protocol_state;
static protocol_state state;
static int has_text(const char *value) {
return value != NULL && value[0] != '\0' && strlen(value) <= 128;
}
static int is_kind(const char *kind, const char *expected) {
return kind != NULL && strcmp(kind, expected) == 0;
}
static int is_side_effect(const char *kind) {
static const char *const commands[] = {
"SESSION_CREATE", "LOAD_PROJECT", "START", "STOP", "RESET",
"LOAD_WORKSPACE", "SIM_STEP", "COMMAND",
"PROGRAM_LOAD", "PROGRAM_RUN", "PROGRAM_PAUSE", "PROGRAM_RESUME",
"PROGRAM_ABORT", "PROGRAM_STEP", "PROGRAM_SEEK", "MDI_EXECUTE",
"JOG_START", "JOG_STOP", "HOME", "SET_MODE", "SET_OVERRIDE",
"SPINDLE_COMMAND", "COOLANT_COMMAND", "TOOL_PREPARE", "TOOL_CHANGE",
"PROBE_CONFIG", "HAL_COMMAND", "HAL_SET", "PLC_START", "PLC_STOP",
"PROJECT_SAVE", "IMPORT", "EXPORT", "CHECKPOINT", "RECOVER",
"SUBSCRIBE", "UNSUBSCRIBE", "CANCEL", NULL,
};
size_t index;
if (!has_text(kind)) return 0;
for (index = 0; commands[index] != NULL; ++index) {
if (is_kind(kind, commands[index])) return 1;
}
return 0;
}
static int state_accepts_kind(uint32_t current, const char *kind) {
if (current == SIM_PROTOCOL_NEW) return is_kind(kind, "HELLO");
if (current == SIM_PROTOCOL_HELLO) return is_kind(kind, "SESSION_ATTACH") || is_kind(kind, "CAPABILITIES");
if (current == SIM_PROTOCOL_ATTACHED) return is_kind(kind, "SESSION_READY");
if (current == SIM_PROTOCOL_READY) return 1;
if (current == SIM_PROTOCOL_PAUSED) {
return is_kind(kind, "PROGRAM_RESUME") || is_kind(kind, "RESUME") ||
is_kind(kind, "PING") || is_kind(kind, "SNAPSHOT_REQUEST") ||
is_kind(kind, "DESTROY");
}
return is_kind(kind, "RESET");
}
void sim_protocol_reset(void) {
memset(&state, 0, sizeof(state));
}
int32_t sim_protocol_accept(uint32_t schema_version, uint32_t seq,
const char *kind, const char *operation_id,
uint32_t simulation_tick) {
if (schema_version != 1U) return SIM_PROTOCOL_ERR_SCHEMA;
if (!has_text(kind)) return SIM_PROTOCOL_ERR_KIND;
if (state.state == SIM_PROTOCOL_DESTROYED && !is_kind(kind, "RESET")) return SIM_PROTOCOL_ERR_STATE;
if (seq == 0U || seq != state.last_seq + 1U) return SIM_PROTOCOL_ERR_SEQUENCE;
if (simulation_tick < state.tick) return SIM_PROTOCOL_ERR_TICK;
if (!state_accepts_kind(state.state, kind)) return SIM_PROTOCOL_ERR_STATE;
if (is_side_effect(kind) && !has_text(operation_id)) return SIM_PROTOCOL_ERR_OPERATION_ID;
state.last_seq = seq;
state.tick = simulation_tick;
if (is_kind(kind, "HELLO")) state.state = SIM_PROTOCOL_HELLO;
/* SESSION_READY is the worker response; the next client command is valid immediately. */
else if (is_kind(kind, "SESSION_ATTACH")) state.state = SIM_PROTOCOL_READY;
else if (is_kind(kind, "SESSION_READY")) state.state = SIM_PROTOCOL_READY;
else if (is_kind(kind, "PROGRAM_PAUSE")) state.state = SIM_PROTOCOL_PAUSED;
else if (is_kind(kind, "PROGRAM_RESUME") || is_kind(kind, "RESUME")) state.state = SIM_PROTOCOL_READY;
else if (is_kind(kind, "DESTROY")) state.state = SIM_PROTOCOL_DESTROYED;
else if (is_kind(kind, "RESET")) sim_protocol_reset();
return SIM_PROTOCOL_OK;
}
int32_t sim_protocol_pause(void) {
if (state.state != SIM_PROTOCOL_READY) return SIM_PROTOCOL_ERR_STATE;
state.state = SIM_PROTOCOL_PAUSED;
return SIM_PROTOCOL_OK;
}
int32_t sim_protocol_resume(void) {
if (state.state != SIM_PROTOCOL_PAUSED) return SIM_PROTOCOL_ERR_STATE;
state.state = SIM_PROTOCOL_READY;
return SIM_PROTOCOL_OK;
}
int32_t sim_protocol_state_value(void) {
return (int32_t)state.state;
}
uint32_t sim_protocol_last_seq(void) {
return state.last_seq;
}
uint32_t sim_protocol_tick(void) {
return state.tick;
}
int32_t sim_protocol_set_tick(uint32_t simulation_tick) {
if (simulation_tick < state.tick) return SIM_PROTOCOL_ERR_TICK;
state.tick = simulation_tick;
return SIM_PROTOCOL_OK;
}