From c0ce5bad26b03cd3e65afa4fc88a38792c206d3d Mon Sep 17 00:00:00 2001 From: IonutParau Date: Mon, 2 Feb 2026 16:35:19 +0100 Subject: [PATCH] more progress --- rewrite/neonucleus.c | 198 ++++++++++++++++++++++++++++++++++++++++++- rewrite/neonucleus.h | 19 +++-- 2 files changed, 205 insertions(+), 12 deletions(-) diff --git a/rewrite/neonucleus.c b/rewrite/neonucleus.c index 54a6e2b..8f60567 100644 --- a/rewrite/neonucleus.c +++ b/rewrite/neonucleus.c @@ -219,6 +219,17 @@ void nn_memset(void *dest, int x, size_t len) { for(size_t i = 0; i < len; i++) out[i] = (char)x; } +int nn_strcmp(const char *a, const char *b) { + size_t i = 0; + while(1) { + char c = a[i]; + char d = b[i]; + if(c == '\0' && d == '\0') return 0; + if(c != d) return (int)(unsigned char)c - (int)(unsigned char)d; + i++; + } +} + nn_Lock *nn_createLock(nn_Context *ctx) { nn_LockRequest req; req.lock = NULL; @@ -445,8 +456,9 @@ typedef struct nn_Computer { nn_Universe *universe; void *userdata; char *address; - const nn_Architecture *arch; - const nn_Architecture *desiredArch; + void *archState; + nn_Architecture arch; + nn_Architecture desiredArch; size_t componentCap; size_t componentLen; nn_Component *components; @@ -541,8 +553,9 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char return NULL; } - c->arch = NULL; - c->desiredArch = NULL; + c->arch.name = NULL; + c->desiredArch.name = NULL; + c->archState = NULL; c->componentCap = maxComponents; c->componentLen = 0; @@ -576,6 +589,15 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char void nn_destroyComputer(nn_Computer *computer) { nn_Context *ctx = &computer->universe->ctx; + if(computer->arch.name != NULL) { + nn_ArchitectureRequest req; + req.computer = computer; + req.globalState = computer->arch.state; + req.localState = computer->archState; + req.action = NN_ARCH_DEINIT; + computer->arch.handler(&req); + } + nn_free(ctx, computer->components, sizeof(nn_Component) * computer->componentCap); nn_free(ctx, computer->deviceInfo, sizeof(nn_DeviceInfo) * computer->deviceInfoCap); nn_strfree(ctx, computer->address); @@ -589,3 +611,171 @@ void *nn_getComputerUserdata(nn_Computer *computer) { const char *nn_getComputerAddress(nn_Computer *computer) { return computer->address; } + +void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch) { + computer->arch = *arch; +} + +nn_Architecture nn_getArchitecture(nn_Computer *computer) { + return computer->arch; +} + +void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch) { + computer->desiredArch = *arch; +} + +nn_Architecture nn_getDesiredArchitecture(nn_Computer *computer) { + return computer->desiredArch; +} + +nn_Exit nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch) { + if(computer->archCount == NN_MAX_ARCHITECTURES) return NN_ELIMIT; + computer->archs[computer->archCount++] = *arch; + return NN_OK; +} + +const nn_Architecture *nn_getSupportedArchitecture(nn_Computer *computer, size_t *len) { + *len = computer->archCount; + return computer->archs; +} + +nn_Architecture nn_findSupportedArchitecture(nn_Computer *computer, const char *name) { + for(size_t i = 0; i < computer->archCount; i++) { + if(nn_strcmp(computer->archs[i].name, name) == 0) return computer->archs[i]; + } + + return (nn_Architecture) { + .name = NULL, + .state = NULL, + .handler = NULL, + }; +} + +void nn_setTotalEnergy(nn_Computer *computer, double maxEnergy) { + computer->totalEnergy = maxEnergy; +} + +double nn_getTotalEnergy(nn_Computer *computer) { + return computer->totalEnergy; +} + +void nn_setEnergy(nn_Computer *computer, double energy) { + computer->energy = energy; +} + +double nn_getEnergy(nn_Computer *computer) { + return computer->energy; +} + +bool nn_removeEnergy(nn_Computer *computer, double energy) { + computer->energy -= energy; + if(computer->energy < 0) computer->energy = 0; + return computer->energy <= 0; +} + +size_t nn_getTotalMemory(nn_Computer *computer) { + return computer->totalMemory; +} + +size_t nn_getFreeMemory(nn_Computer *computer) { + if(computer->state == NN_BOOTUP) return 0; + nn_ArchitectureRequest req; + req.computer = computer; + req.action = NN_ARCH_FREEMEM; + req.globalState = computer->arch.state; + req.localState = computer->archState; + + computer->arch.handler(&req); + return req.freeMemory; +} + +double nn_getUptime(nn_Computer *computer) { + return nn_currentTime(&computer->universe->ctx) - computer->creationTimestamp; +} + + +void nn_setError(nn_Computer *computer, const char *s) { + nn_setLError(computer, s, nn_strlen(s)); +} + +void nn_setLError(nn_Computer *computer, const char *s, size_t len) { + if(len >= NN_MAX_ERROR_SIZE) len = NN_MAX_ERROR_SIZE - 1; + nn_memcpy(computer->errorBuffer, s, sizeof(char) * len); + computer->errorBuffer[len] = '\0'; +} + +const char *nn_getError(nn_Computer *computer) { + return computer->errorBuffer; +} + +void nn_clearError(nn_Computer *computer) { + // make it empty + computer->errorBuffer[0] = '\0'; +} + +void nn_setComputerState(nn_Computer *computer, nn_ComputerState state) { + computer->state = state; +} + +nn_ComputerState nn_getComputerState(nn_Computer *computer) { + return computer->state; +} + +static void nn_setErrorFromExit(nn_Computer *computer, nn_Exit exit) { + switch(exit) { + case NN_OK: + return; // no error + case NN_EBADCALL: + return; // stored by component + case NN_ENOMEM: + nn_setError(computer, "out of memory"); + return; + case NN_ELIMIT: + nn_setError(computer, "buffer overflow"); + return; + case NN_ENOSTACK: + nn_setError(computer, "stack overflow"); + return; + case NN_EBELOWSTACK: + nn_setError(computer, "stack underflow"); + return; + case NN_EBADSTATE: + nn_setError(computer, "bad state"); + return; + } +} + +nn_Exit nn_tick(nn_Computer *computer) { + nn_Exit err; + if(computer->state == NN_BOOTUP) { + // init state + nn_ArchitectureRequest req; + req.computer = computer; + 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) { + nn_setErrorFromExit(computer, NN_EBADSTATE); + return NN_EBADSTATE; + } + computer->state = NN_RUNNING; + nn_ArchitectureRequest req; + req.computer = computer; + req.globalState = computer->arch.state; + req.localState = computer->archState; + req.action = NN_ARCH_TICK; + err = computer->arch.handler(&req); + if(err) { + computer->state = NN_CRASHED; + nn_setErrorFromExit(computer, err); + return err; + } + return NN_OK; +} diff --git a/rewrite/neonucleus.h b/rewrite/neonucleus.h index 9b63157..40e4946 100644 --- a/rewrite/neonucleus.h +++ b/rewrite/neonucleus.h @@ -137,6 +137,8 @@ typedef enum nn_Exit { NN_ENOSTACK, // bad invocation, error message stored in computer state NN_EBADCALL, + // bad state, the function was called at the wrong time + NN_EBADSTATE, } nn_Exit; // This stores necessary data between computers @@ -220,24 +222,25 @@ const char *nn_getComputerAddress(nn_Computer *computer); // Sets the computer's architecture. // The architecture determines everything from how the computer runs, to how it turns off. // Everything is limited by the architecture. -// The architecture is not copied, it must be valid for as long as the computer is. +// The architecture is copied, it can be freed after this is called. void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch); // Gets the current architecture. -const nn_Architecture *nn_getArchitecture(nn_Computer *computer); +nn_Architecture nn_getArchitecture(nn_Computer *computer); // Sets the computer's desired architecture. // The desired architecture indicates, when the computer state is CHARCH, what the new architecture should be. // This is set even if it is not in the supported architecture list, *you must check if it is in that list first.* -// The architecture is not copied, it must be valid for as long as the computer is. +// The architecture is copied, it can be freed after this is called. void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch); // Gets the desired architecture. This is the architecture the computer should use after changing architectures. -const nn_Architecture *nn_getDesiredArchitecture(nn_Computer *computer); +nn_Architecture nn_getDesiredArchitecture(nn_Computer *computer); // Adds a new supported architecture, which indicates to the code running on this computer that it is possible to switch to that architecture. // The architecture is copied, it can be freed after this is called. -void nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch); +nn_Exit nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch); // Returns the array of supported architectures, as well as the length. const nn_Architecture *nn_getSupportedArchitecture(nn_Computer *computer, size_t *len); // Helper function for searching for an architecture using a computer which supports it and the architecture name. -const nn_Architecture *nn_findSupportedArchitecture(nn_Computer *computer, const char *name); +// If the architecture is not found, it returns one with a NULL name. +nn_Architecture nn_findSupportedArchitecture(nn_Computer *computer, const char *name); // sets the energy capacity of the computer. void nn_setTotalEnergy(nn_Computer *computer, double maxEnergy); @@ -270,8 +273,8 @@ void nn_setComputerState(nn_Computer *computer, nn_ComputerState state); // gets the current computer state nn_ComputerState nn_getComputerState(nn_Computer *computer); -// runs a tick of the computer. Make sure to check the state returned! -nn_ComputerState nn_tick(nn_Computer *computer); +// runs a tick of the computer. Make sure to check the state as well! +nn_Exit nn_tick(nn_Computer *computer); typedef struct nn_DeviceInfoEntry { const char *name;