computers can be turned on/off now

This commit is contained in:
2026-04-07 13:11:18 +02:00
parent 5d7725d77b
commit 82777b52b3
4 changed files with 143 additions and 30 deletions

View File

@@ -116,6 +116,27 @@ static void luaArch_nnToLua(luaArch *arch, lua_State *L, size_t nnIdx) {
luaL_error(L, "bad NN value: %s", nn_typenameof(C, nnIdx)); luaL_error(L, "bad NN value: %s", nn_typenameof(C, nnIdx));
} }
static int luaArch_computer_beep(lua_State *L) {
nn_Beep beep = {.frequency = 1000, .duration = 1, .volume = 1};
if(lua_isnumber(L, 1)) {
beep.frequency = lua_tonumber(L, 1);
}
if(lua_isnumber(L, 2)) {
beep.duration = lua_tonumber(L, 2);
}
if(lua_isnumber(L, 3)) {
beep.volume = lua_tonumber(L, 3);
}
if(beep.frequency < 20) beep.frequency = 20;
if(beep.duration < 0) beep.duration = 0;
if(beep.volume < 0) beep.volume = 0;
if(beep.frequency > 20000) beep.frequency = 20000;
if(beep.duration > 5) beep.duration = 5;
if(beep.volume > 1) beep.volume = 1;
nn_setComputerBeep(luaArch_from(L)->computer, beep);
return 0;
}
static int luaArch_computer_freeMemory(lua_State *L) { static int luaArch_computer_freeMemory(lua_State *L) {
lua_pushinteger(L, nn_getFreeMemory(luaArch_from(L)->computer)); lua_pushinteger(L, nn_getFreeMemory(luaArch_from(L)->computer));
return 1; return 1;
@@ -531,6 +552,8 @@ static int luaArch_unicode_wtrunc(lua_State *L) {
static void luaArch_loadEnv(lua_State *L) { static void luaArch_loadEnv(lua_State *L) {
lua_createtable(L, 0, 10); lua_createtable(L, 0, 10);
int computer = lua_gettop(L); int computer = lua_gettop(L);
lua_pushcfunction(L, luaArch_computer_beep);
lua_setfield(L, computer, "beep");
lua_pushcfunction(L, luaArch_computer_freeMemory); lua_pushcfunction(L, luaArch_computer_freeMemory);
lua_setfield(L, computer, "freeMemory"); lua_setfield(L, computer, "freeMemory");
lua_pushcfunction(L, luaArch_computer_totalMemory); lua_pushcfunction(L, luaArch_computer_totalMemory);

View File

@@ -457,7 +457,6 @@ int main(int argc, char **argv) {
} }
} }
restart:;
nn_Computer *c = nn_createComputer(u, NULL, "computer0", ramTotal, 256, 256); nn_Computer *c = nn_createComputer(u, NULL, "computer0", ramTotal, 256, 256);
if(showStats) { if(showStats) {
// collects stats // collects stats
@@ -549,6 +548,11 @@ restart:;
if(t != NULL) nn_pushClipboard(c, "mainKB", t, player); if(t != NULL) nn_pushClipboard(c, "mainKB", t, player);
} }
if(IsKeyPressed(KEY_TAB)) {
printf("force crashing\n");
nn_forceCrashComputer(c, "get crashed lol");
}
while(1) { while(1) {
int keycode = GetKeyPressed(); int keycode = GetKeyPressed();
nn_codepoint unicode = GetCharPressed(); nn_codepoint unicode = GetCharPressed();
@@ -574,6 +578,11 @@ restart:;
keybuf[i].key = 0; keybuf[i].key = 0;
nn_pushKeyUp(c, "mainKB", keybuf[i].unicode, key, player); nn_pushKeyUp(c, "mainKB", keybuf[i].unicode, key, player);
} }
// unicode keys handled by raylib
if(IsKeyPressedRepeat(keybuf[i].key) && keybuf[i].unicode == 0) {
int key = keycode_to_oc(keybuf[i].key);
nn_pushKeyDown(c, "mainKB", keybuf[i].unicode, key, player);
}
} }
} }
@@ -594,7 +603,6 @@ restart:;
if(getenv("NN_NOIDLE") != NULL) nn_resetIdleTime(c); if(getenv("NN_NOIDLE") != NULL) nn_resetIdleTime(c);
nn_Exit e = nn_tick(c); nn_Exit e = nn_tick(c);
if(e != NN_OK) { if(e != NN_OK) {
nn_setErrorFromExit(c, e);
printf("error: %s\n", nn_getError(c)); printf("error: %s\n", nn_getError(c));
goto cleanup; goto cleanup;
} }
@@ -616,10 +624,18 @@ restart:;
} }
if(state == NN_RESTART) { if(state == NN_RESTART) {
printf("restart requested\n"); printf("restart requested\n");
nn_destroyComputer(c); nn_stopComputer(c);
goto restart; ncl_resetScreen(nn_getComponentState(screen));
nn_addIdleTime(c, 1);
continue;
} }
} }
nn_Beep beep;
if(nn_getComputerBeep(c, &beep)) {
nn_clearComputerBeep(c);
printf("beep: %f Hz, %fs, %f%% volume\n", beep.frequency, beep.duration, beep.volume * 100);
}
} }
cleanup:; cleanup:;

View File

@@ -784,6 +784,15 @@ void nn_hashDeinit(nn_HashMap *map) {
nn_free(map->ctx, map->buf, map->hash->entSize * map->bufsize); nn_free(map->ctx, map->buf, map->hash->entSize * map->bufsize);
} }
void nn_hashClear(nn_HashMap *map) {
for(size_t i = 0; i < map->bufsize; i++) {
void *ent = NN_PTROFF(map->buf, i, map->hash->entSize);
if(map->hash->handler(NN_HASH_CMP, ent, NULL) == NN_HASH_DIFFERENT) {
map->hash->handler(NN_HASH_REMOVE, ent, NULL);
}
}
}
size_t nn_hashGetHash(nn_HashMap *map, void *entry) { size_t nn_hashGetHash(nn_HashMap *map, void *entry) {
return map->hash->handler(NN_HASH_HASH, entry, NULL); return map->hash->handler(NN_HASH_HASH, entry, NULL);
} }
@@ -1044,6 +1053,7 @@ typedef struct nn_Computer {
size_t userCount; size_t userCount;
double idleTimestamp; double idleTimestamp;
double memoryScale; double memoryScale;
nn_Beep beep;
nn_Value callstack[NN_MAX_STACK]; nn_Value callstack[NN_MAX_STACK];
char errorBuffer[NN_MAX_ERROR_SIZE]; char errorBuffer[NN_MAX_ERROR_SIZE];
nn_Architecture archs[NN_MAX_ARCHITECTURES]; nn_Architecture archs[NN_MAX_ARCHITECTURES];
@@ -1169,6 +1179,7 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char
c->memoryScale = 1; c->memoryScale = 1;
// set to empty string // set to empty string
c->errorBuffer[0] = '\0'; c->errorBuffer[0] = '\0';
nn_clearComputerBeep(c);
return c; return c;
} }
@@ -1196,34 +1207,86 @@ static const nn_MethodEntry *nn_getInternalMethod(nn_Component *c, const char *m
return nn_hashGet(&c->methodsMap, &lookingFor); return nn_hashGet(&c->methodsMap, &lookingFor);
} }
void nn_destroyComputer(nn_Computer *computer) { nn_Exit nn_startComputer(nn_Computer *computer) {
nn_Context *ctx = &computer->universe->ctx; if(nn_isComputerOn(computer)) {
nn_stopComputer(computer);
}
nn_ArchitectureRequest req;
req.computer = computer;
req.globalState = computer->arch.state;
req.localState = NULL;
req.action = NN_ARCH_INIT;
nn_Exit err = computer->arch.handler(&req);
if(err) {
computer->state = NN_CRASHED;
nn_setErrorFromExit(computer, err);
return err;
}
computer->archState = req.localState;
return NN_OK;
}
if(computer->arch.name != NULL && computer->archState != NULL) { void nn_stopComputer(nn_Computer *computer) {
nn_Context *ctx = &computer->universe->ctx;
if(nn_isComputerOn(computer)) {
nn_ArchitectureRequest req; nn_ArchitectureRequest req;
req.computer = computer; req.computer = computer;
req.globalState = computer->arch.state; req.globalState = computer->arch.state;
req.localState = computer->archState; req.localState = computer->archState;
req.action = NN_ARCH_DEINIT; req.action = NN_ARCH_DEINIT;
computer->arch.handler(&req); computer->arch.handler(&req);
computer->archState = NULL;
} }
computer->state = NN_BOOTUP;
for(size_t i = 0; i < computer->stackSize; i++) {
nn_dropValue(computer->callstack[i]);
}
for(nn_ComponentEntry *c = nn_hashIterate(&computer->components, NULL); c != NULL; c = nn_hashIterate(&computer->components, c)) {
nn_signalComponent(c->comp, computer, NN_CSIGUNMOUNTED);
nn_dropComponent(c->comp);
}
for(size_t i = 0; i < computer->signalCount; i++) { for(size_t i = 0; i < computer->signalCount; i++) {
nn_Signal s = computer->signals[i]; nn_Signal s = computer->signals[i];
for(size_t j = 0; j < s.len; j++) nn_dropValue(s.values[j]); for(size_t j = 0; j < s.len; j++) nn_dropValue(s.values[j]);
nn_free(ctx, s.values, sizeof(nn_Value) * s.len); nn_free(ctx, s.values, sizeof(nn_Value) * s.len);
} }
computer->signalCount = 0;
}
void nn_forceCrashComputer(nn_Computer *computer, const char *s) {
nn_stopComputer(computer);
computer->state = NN_CRASHED;
nn_setError(computer, s);
}
bool nn_isComputerOn(nn_Computer *computer) {
return computer->archState != NULL;
}
void nn_setComputerBeep(nn_Computer *computer, nn_Beep beep) {
if(beep.duration < 0) beep.duration = 0;
computer->beep = beep;
nn_addIdleTime(computer, beep.duration);
}
bool nn_getComputerBeep(nn_Computer *computer, nn_Beep *beep) {
*beep = computer->beep;
return computer->beep.volume > 0;
}
void nn_clearComputerBeep(nn_Computer *computer) {
computer->beep.volume = 0;
}
void nn_destroyComputer(nn_Computer *computer) {
nn_Context *ctx = &computer->universe->ctx;
nn_stopComputer(computer);
for(size_t i = 0; i < computer->stackSize; i++) {
nn_dropValue(computer->callstack[i]);
}
for(size_t i = 0; i < computer->userCount; i++) { for(size_t i = 0; i < computer->userCount; i++) {
nn_strfree(ctx, computer->users[i]); nn_strfree(ctx, computer->users[i]);
} }
for(nn_ComponentEntry *c = nn_hashIterate(&computer->components, NULL); c != NULL; c = nn_hashIterate(&computer->components, c)) {
nn_signalComponent(c->comp, computer, NN_CSIGUNMOUNTED);
nn_dropComponent(c->comp);
}
nn_destroyLock(ctx, computer->lock);
nn_hashDeinit(&computer->components); nn_hashDeinit(&computer->components);
if(computer->tmpaddress != NULL) nn_strfree(ctx, computer->tmpaddress); if(computer->tmpaddress != NULL) nn_strfree(ctx, computer->tmpaddress);
nn_strfree(ctx, computer->address); nn_strfree(ctx, computer->address);
@@ -1522,6 +1585,9 @@ void nn_resetIdleTime(nn_Computer *computer) {
} }
nn_Exit nn_tick(nn_Computer *computer) { nn_Exit nn_tick(nn_Computer *computer) {
if(computer->state == NN_CRASHED) {
return NN_EBADSTATE;
}
nn_resetCallBudget(computer); nn_resetCallBudget(computer);
nn_resetComponentBudgets(computer); nn_resetComponentBudgets(computer);
nn_clearstack(computer); nn_clearstack(computer);
@@ -1531,20 +1597,10 @@ nn_Exit nn_tick(nn_Computer *computer) {
computer->idleTimestamp = nn_getUptime(computer); computer->idleTimestamp = nn_getUptime(computer);
if(computer->state == NN_BOOTUP) { if(computer->state == NN_BOOTUP) {
// init state // init state
nn_ArchitectureRequest req; err = nn_startComputer(computer);
req.computer = computer; if(err) return err;
req.globalState = computer->arch.state;
req.localState = NULL;
req.action = NN_ARCH_INIT;
err = computer->arch.handler(&req);
if(err) {
computer->state = NN_CRASHED;
nn_setErrorFromExit(computer, err);
return err;
}
computer->archState = req.localState;
} else if(computer->state != NN_RUNNING) { } else if(computer->state != NN_RUNNING) {
nn_setErrorFromExit(computer, NN_EBADSTATE); if(computer->state != NN_CRASHED) nn_setErrorFromExit(computer, NN_EBADSTATE);
return NN_EBADSTATE; return NN_EBADSTATE;
} }
computer->state = NN_RUNNING; computer->state = NN_RUNNING;
@@ -1562,8 +1618,6 @@ nn_Exit nn_tick(nn_Computer *computer) {
return NN_OK; return NN_OK;
} }
// TODO: every component method src/neonucleus.h:530
static nn_Exit nn_defaultComponent(nn_ComponentRequest *request) { static nn_Exit nn_defaultComponent(nn_ComponentRequest *request) {
return NN_OK; return NN_OK;
} }

View File

@@ -410,6 +410,26 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char
void nn_destroyComputer(nn_Computer *computer); void nn_destroyComputer(nn_Computer *computer);
void nn_lockComputer(nn_Computer *computer); void nn_lockComputer(nn_Computer *computer);
void nn_unlockComputer(nn_Computer *computer); void nn_unlockComputer(nn_Computer *computer);
// stops the computer if an architecture state is already present,
// will also clear the signal buffer and set the state to NN_BOOTUP.
nn_Exit nn_startComputer(nn_Computer *computer);
// destroys the architecture state if present.
// Will also do other shutdown routines, such as unmounting every
void nn_stopComputer(nn_Computer *computer);
void nn_forceCrashComputer(nn_Computer *computer, const char *s);
// returns whether an architecture state is present
bool nn_isComputerOn(nn_Computer *computer);
typedef struct nn_Beep {
double frequency;
double duration;
double volume;
} nn_Beep;
void nn_setComputerBeep(nn_Computer *computer, nn_Beep beep);
bool nn_getComputerBeep(nn_Computer *computer, nn_Beep *beep);
void nn_clearComputerBeep(nn_Computer *computer);
// get the userdata pointer // get the userdata pointer
void *nn_getComputerUserdata(nn_Computer *computer); void *nn_getComputerUserdata(nn_Computer *computer);
const char *nn_getComputerAddress(nn_Computer *computer); const char *nn_getComputerAddress(nn_Computer *computer);