rename ctypes to cstates

This commit is contained in:
2026-02-24 09:27:53 +01:00
parent e376d4a002
commit e94b656436
4 changed files with 62 additions and 64 deletions

View File

@@ -7,8 +7,6 @@
# To re-evaluate # To re-evaluate
- The current system has the computer store the components and the component *types* store the state. Perhaps the ComponentType struct should be renamed
to ComponentState.
- More stack manipulation functions to allow libraries to have more APIs. - More stack manipulation functions to allow libraries to have more APIs.
- Having a copy of the context stored directly in requests instead of having to use getComputerContext, as it simplifies the APIs and allows them - Having a copy of the context stored directly in requests instead of having to use getComputerContext, as it simplifies the APIs and allows them
to be made more portable. to be made more portable.

View File

@@ -1029,7 +1029,7 @@ int main() {
{"log", "log(msg: string) - Log to stdout", true}, {"log", "log(msg: string) - Log to stdout", true},
{NULL}, {NULL},
}; };
nn_ComponentType *ctype = nn_createComponentType(u, "sandbox", NULL, sandboxMethods, sandbox_handler); nn_ComponentState *sandstate = nn_createComponentState(u, "sandbox", NULL, sandboxMethods, sandbox_handler);
nn_VEEPROM veeprom = { nn_VEEPROM veeprom = {
.code = minBIOS, .code = minBIOS,
@@ -1042,15 +1042,15 @@ int main() {
.isReadonly = false, .isReadonly = false,
}; };
nn_ComponentType *etype = nn_createVEEPROM(u, &nn_defaultEEPROMs[3], &veeprom); nn_ComponentState *etype = nn_createVEEPROM(u, &nn_defaultEEPROMs[3], &veeprom);
nn_ComponentType *fstype[5]; nn_ComponentState *fstype[5];
fstype[0] = nn_createFilesystem(u, &nn_defaultFloppy, ne_fsState_handler, NULL); fstype[0] = nn_createFilesystem(u, &nn_defaultFloppy, ne_fsState_handler, NULL);
for(size_t i = 1; i < 5; i++) { for(size_t i = 1; i < 5; i++) {
fstype[i] = nn_createFilesystem(u, &nn_defaultFilesystems[i-1], ne_fsState_handler, NULL); fstype[i] = nn_createFilesystem(u, &nn_defaultFilesystems[i-1], ne_fsState_handler, NULL);
} }
nn_ComponentType *scrtype = nn_createScreen(u, ne_screen_handler, NULL); nn_ComponentState *scrtype = nn_createScreen(u, ne_screen_handler, NULL);
nn_ComponentType *keytype = nn_createKeyboard(u); nn_ComponentState *keytype = nn_createKeyboard(u);
nn_ComponentType *gputype = nn_createGPU(u, &nn_defaultGPUs[3], ne_gpu_handler, NULL); nn_ComponentState *gputype = nn_createGPU(u, &nn_defaultGPUs[3], ne_gpu_handler, NULL);
nn_Computer *c = nn_createComputer(u, NULL, "computer0", 8 * NN_MiB, 256, 256); nn_Computer *c = nn_createComputer(u, NULL, "computer0", 8 * NN_MiB, 256, 256);
if(showStats) { if(showStats) {
@@ -1061,10 +1061,10 @@ int main() {
nn_setArchitecture(c, &arch); nn_setArchitecture(c, &arch);
nn_addSupportedArchitecture(c, &arch); nn_addSupportedArchitecture(c, &arch);
nn_addComponent(c, ctype, "sandbox", -1, NULL); nn_addComponent(c, sandstate, "sandbox", -1, NULL);
nn_addComponent(c, etype, "eeprom", 0, etype); nn_addComponent(c, etype, "eeprom", 0, etype);
ne_FsState *mainFS = ne_newFS("OpenOS", true); ne_FsState *mainFS = ne_newFS("OpenOS", false);
nn_addComponent(c, fstype[4], "mainFS", 2, mainFS); nn_addComponent(c, fstype[4], "mainFS", 2, mainFS);
nn_addComponent(c, keytype, "mainKB", 4, NULL); nn_addComponent(c, keytype, "mainKB", 4, NULL);
@@ -1207,12 +1207,12 @@ int main() {
cleanup:; cleanup:;
nn_destroyComputer(c); nn_destroyComputer(c);
nn_destroyComponentType(ctype); nn_destroyComponentState(sandstate);
nn_destroyComponentType(etype); nn_destroyComponentState(etype);
nn_destroyComponentType(scrtype); nn_destroyComponentState(scrtype);
nn_destroyComponentType(keytype); nn_destroyComponentState(keytype);
nn_destroyComponentType(gputype); nn_destroyComponentState(gputype);
for(size_t i = 0; i < 5; i++) nn_destroyComponentType(fstype[i]); for(size_t i = 0; i < 5; i++) nn_destroyComponentState(fstype[i]);
ne_dropScreenBuf(&ctx, scrbuf); ne_dropScreenBuf(&ctx, scrbuf);
// rip the universe // rip the universe
nn_destroyUniverse(u); nn_destroyUniverse(u);

View File

@@ -546,7 +546,7 @@ void nn_initContext(nn_Context *ctx) {
ctx->lock = nn_defaultLock; ctx->lock = nn_defaultLock;
} }
typedef struct nn_ComponentType { typedef struct nn_ComponentState {
nn_Universe *universe; nn_Universe *universe;
void *userdata; void *userdata;
nn_Arena arena; nn_Arena arena;
@@ -555,7 +555,7 @@ typedef struct nn_ComponentType {
// NULL-terminated // NULL-terminated
nn_Method *methods; nn_Method *methods;
size_t methodCount; size_t methodCount;
} nn_ComponentType; } nn_ComponentState;
// currently just a wrapper around a context // currently just a wrapper around a context
// but will be way more in the future // but will be way more in the future
@@ -565,7 +565,7 @@ typedef struct nn_Universe {
typedef struct nn_Component { typedef struct nn_Component {
char *address; char *address;
nn_ComponentType *ctype; nn_ComponentState *cstate;
int slot; int slot;
float budgetUsed; float budgetUsed;
void *userdata; void *userdata;
@@ -668,10 +668,10 @@ void nn_destroyUniverse(nn_Universe *universe) {
nn_free(&ctx, universe, sizeof(nn_Universe)); nn_free(&ctx, universe, sizeof(nn_Universe));
} }
nn_ComponentType *nn_createComponentType(nn_Universe *universe, const char *name, void *userdata, const nn_Method methods[], nn_ComponentHandler *handler) { nn_ComponentState *nn_createComponentState(nn_Universe *universe, const char *name, void *userdata, const nn_Method methods[], nn_ComponentHandler *handler) {
nn_Context *ctx = &universe->ctx; nn_Context *ctx = &universe->ctx;
nn_ComponentType *ctype = nn_alloc(ctx, sizeof(nn_ComponentType)); nn_ComponentState *ctype = nn_alloc(ctx, sizeof(nn_ComponentState));
if(ctype == NULL) return NULL; if(ctype == NULL) return NULL;
ctype->universe = universe; ctype->universe = universe;
ctype->userdata = userdata; ctype->userdata = userdata;
@@ -706,11 +706,11 @@ nn_ComponentType *nn_createComponentType(nn_Universe *universe, const char *name
return ctype; return ctype;
fail:; fail:;
// yes, because of arenas, we support freeing a "partially initialized state" // yes, because of arenas, we support freeing a "partially initialized state"
nn_destroyComponentType(ctype); nn_destroyComponentState(ctype);
return NULL; return NULL;
} }
void nn_destroyComponentType(nn_ComponentType *ctype) { void nn_destroyComponentState(nn_ComponentState *ctype) {
if(ctype == NULL) return; if(ctype == NULL) return;
nn_Context *ctx = &ctype->universe->ctx; nn_Context *ctx = &ctype->universe->ctx;
@@ -725,7 +725,7 @@ void nn_destroyComponentType(nn_ComponentType *ctype) {
ctype->handler(&req); ctype->handler(&req);
nn_ardestroy(&ctype->arena); nn_ardestroy(&ctype->arena);
nn_free(ctx, ctype, sizeof(nn_ComponentType)); nn_free(ctx, ctype, sizeof(nn_ComponentState));
} }
double nn_default_energyHandler(void *state, nn_Computer *computer, double amount) { double nn_default_energyHandler(void *state, nn_Computer *computer, double amount) {
@@ -1094,13 +1094,13 @@ nn_Exit nn_tick(nn_Computer *computer) {
return NN_OK; return NN_OK;
} }
nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentType *ctype, const char *address, int slot, void *userdata) { nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentState *ctype, const char *address, int slot, void *userdata) {
if(computer->componentLen == computer->componentCap) return NN_ELIMIT; if(computer->componentLen == computer->componentCap) return NN_ELIMIT;
nn_Component c; nn_Component c;
c.address = nn_strdup(&computer->universe->ctx, address); c.address = nn_strdup(&computer->universe->ctx, address);
if(c.address == NULL) return NN_ENOMEM; if(c.address == NULL) return NN_ENOMEM;
c.ctype = ctype; c.cstate = ctype;
c.slot = slot; c.slot = slot;
c.userdata = userdata; c.userdata = userdata;
c.state = NULL; c.state = NULL;
@@ -1154,15 +1154,15 @@ bool nn_hasMethod(nn_Computer *computer, const char *address, const char *method
if(nn_strcmp(c->address, address) != 0) continue; if(nn_strcmp(c->address, address) != 0) continue;
bool found = false; bool found = false;
for(size_t j = 0; j < c->ctype->methodCount; j++) { for(size_t j = 0; j < c->cstate->methodCount; j++) {
if(nn_strcmp(c->ctype->methods[j].name, method) != 0) continue; if(nn_strcmp(c->cstate->methods[j].name, method) != 0) continue;
found = true; found = true;
break; break;
} }
if(!found) return false; if(!found) return false;
nn_ComponentRequest req; nn_ComponentRequest req;
req.typeUserdata = c->ctype->userdata; req.typeUserdata = c->cstate->userdata;
req.compUserdata = c->userdata; req.compUserdata = c->userdata;
req.state = c->state; req.state = c->state;
req.computer = computer; req.computer = computer;
@@ -1172,7 +1172,7 @@ bool nn_hasMethod(nn_Computer *computer, const char *address, const char *method
// default response in case it is not implemented // default response in case it is not implemented
req.methodEnabled = true; req.methodEnabled = true;
// should never error // should never error
c->ctype->handler(&req); c->cstate->handler(&req);
return req.methodEnabled; return req.methodEnabled;
} }
@@ -1181,7 +1181,7 @@ bool nn_hasMethod(nn_Computer *computer, const char *address, const char *method
static void nn_dropComponent(nn_Computer *computer, nn_Component c) { static void nn_dropComponent(nn_Computer *computer, nn_Component c) {
nn_ComponentRequest req; nn_ComponentRequest req;
req.typeUserdata = c.ctype->userdata; req.typeUserdata = c.cstate->userdata;
req.compUserdata = c.userdata; req.compUserdata = c.userdata;
req.state = c.state; req.state = c.state;
req.computer = computer; req.computer = computer;
@@ -1189,7 +1189,7 @@ static void nn_dropComponent(nn_Computer *computer, nn_Component c) {
req.action = NN_COMP_DEINIT; req.action = NN_COMP_DEINIT;
req.methodCalled = NULL; req.methodCalled = NULL;
c.ctype->handler(&req); c.cstate->handler(&req);
nn_strfree(&computer->universe->ctx, c.address); nn_strfree(&computer->universe->ctx, c.address);
} }
@@ -1218,7 +1218,7 @@ nn_Exit nn_removeComponent(nn_Computer *computer, const char *address) {
err = nn_pushstring(computer, address); err = nn_pushstring(computer, address);
if(err) return err; if(err) return err;
// not a UAF because c is on-stack // not a UAF because c is on-stack
err = nn_pushstring(computer, c.ctype->name); err = nn_pushstring(computer, c.cstate->name);
if(err) return err; if(err) return err;
err = nn_pushSignal(computer, 3); err = nn_pushSignal(computer, 3);
if(err) return err; if(err) return err;
@@ -1230,7 +1230,7 @@ const char *nn_getComponentType(nn_Computer *computer, const char *address) {
for(size_t i = 0; i < computer->componentLen; i++) { for(size_t i = 0; i < computer->componentLen; i++) {
nn_Component *c = &computer->components[i]; nn_Component *c = &computer->components[i];
if(nn_strcmp(c->address, address) == 0) { if(nn_strcmp(c->address, address) == 0) {
return c->ctype->name; return c->cstate->name;
} }
} }
return NULL; return NULL;
@@ -1250,8 +1250,8 @@ const nn_Method *nn_getComponentMethods(nn_Computer *computer, const char *addre
for(size_t i = 0; i < computer->componentLen; i++) { for(size_t i = 0; i < computer->componentLen; i++) {
nn_Component *c = &computer->components[i]; nn_Component *c = &computer->components[i];
if(nn_strcmp(c->address, address) == 0) { if(nn_strcmp(c->address, address) == 0) {
if(len != NULL) *len = c->ctype->methodCount; if(len != NULL) *len = c->cstate->methodCount;
return c->ctype->methods; return c->cstate->methods;
} }
} }
if(len != NULL) *len = 0; if(len != NULL) *len = 0;
@@ -1274,8 +1274,8 @@ const char *nn_getComponentDoc(nn_Computer *computer, const char *address, const
nn_Component c = computer->components[i]; nn_Component c = computer->components[i];
if(nn_strcmp(c.address, address) != 0) continue; if(nn_strcmp(c.address, address) != 0) continue;
for(size_t j = 0; j < c.ctype->methodCount; j++) { for(size_t j = 0; j < c.cstate->methodCount; j++) {
if(nn_strcmp(c.ctype->methods[j].name, method) == 0) return c.ctype->methods[j].docString; if(nn_strcmp(c.cstate->methods[j].name, method) == 0) return c.cstate->methods[j].docString;
} }
return NULL; return NULL;
} }
@@ -1349,15 +1349,15 @@ nn_Exit nn_call(nn_Computer *computer, const char *address, const char *method)
// minimum cost of a component call // minimum cost of a component call
if(computer->callBudget > 0) computer->callBudget--; if(computer->callBudget > 0) computer->callBudget--;
for(size_t j = 0; j < c.ctype->methodCount; j++) { for(size_t j = 0; j < c.cstate->methodCount; j++) {
nn_Method m = c.ctype->methods[j]; nn_Method m = c.cstate->methods[j];
if(nn_strcmp(m.name, method) != 0) continue; if(nn_strcmp(m.name, method) != 0) continue;
// indirect calls consume the entire call budget // indirect calls consume the entire call budget
if((m.flags & NN_DIRECT) == NN_INDIRECT) computer->callBudget = 0; if((m.flags & NN_DIRECT) == NN_INDIRECT) computer->callBudget = 0;
} }
nn_ComponentRequest req; nn_ComponentRequest req;
req.typeUserdata = c.ctype->userdata; req.typeUserdata = c.cstate->userdata;
req.compUserdata = c.userdata; req.compUserdata = c.userdata;
req.state = c.state; req.state = c.state;
req.computer = computer; req.computer = computer;
@@ -1367,7 +1367,7 @@ nn_Exit nn_call(nn_Computer *computer, const char *address, const char *method)
// default is to return nothing // default is to return nothing
req.returnCount = 0; req.returnCount = 0;
nn_Exit err = c.ctype->handler(&req); nn_Exit err = c.cstate->handler(&req);
if(err) { if(err) {
if(err != NN_EBADCALL) nn_setErrorFromExit(computer, err); if(err != NN_EBADCALL) nn_setErrorFromExit(computer, err);
// clear junk // clear junk
@@ -2113,7 +2113,7 @@ nn_EEPROM nn_defaultEEPROMs[4] = {
}, },
}; };
nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata) { nn_ComponentState *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata) {
nn_Context ctx = universe->ctx; nn_Context ctx = universe->ctx;
nn_EEPROM_state *state = nn_alloc(&ctx, sizeof(*state)); nn_EEPROM_state *state = nn_alloc(&ctx, sizeof(*state));
if(state == NULL) return NULL; if(state == NULL) return NULL;
@@ -2137,7 +2137,7 @@ nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom
{"getChecksum", "function(): string - Returns a simple checksum of the EEPROM's contents and data.", NN_INDIRECT}, {"getChecksum", "function(): string - Returns a simple checksum of the EEPROM's contents and data.", NN_INDIRECT},
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
}; };
nn_ComponentType *t = nn_createComponentType(universe, "eeprom", state, methods, nn_eeprom_handler); nn_ComponentState *t = nn_createComponentState(universe, "eeprom", state, methods, nn_eeprom_handler);
if(t == NULL) { if(t == NULL) {
nn_free(&ctx, state, sizeof(*state)); nn_free(&ctx, state, sizeof(*state));
return NULL; return NULL;
@@ -2197,7 +2197,7 @@ static nn_Exit nn_veeprom_handler(nn_EEPROMRequest *req) {
return NN_OK; return NN_OK;
} }
nn_ComponentType *nn_createVEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const nn_VEEPROM *vmem) { nn_ComponentState *nn_createVEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const nn_VEEPROM *vmem) {
nn_Context ctx = universe->ctx; nn_Context ctx = universe->ctx;
char *code = NULL; char *code = NULL;
char *data = NULL; char *data = NULL;
@@ -2229,7 +2229,7 @@ nn_ComponentType *nn_createVEEPROM(nn_Universe *universe, const nn_EEPROM *eepro
state->archlen = archlen; state->archlen = archlen;
nn_memcpy(state->arch, vmem->arch, sizeof(char) * archlen); nn_memcpy(state->arch, vmem->arch, sizeof(char) * archlen);
nn_ComponentType *ty = nn_createEEPROM(universe, eeprom, nn_veeprom_handler, state); nn_ComponentState *ty = nn_createEEPROM(universe, eeprom, nn_veeprom_handler, state);
if(ty == NULL) goto fail; if(ty == NULL) goto fail;
return ty; return ty;
fail:; fail:;
@@ -2582,7 +2582,7 @@ nn_Exit nn_filesystem_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
} }
nn_ComponentType *nn_createFilesystem(nn_Universe *universe, const nn_Filesystem *filesystem, nn_FilesystemHandler *handler, void *userdata) { nn_ComponentState *nn_createFilesystem(nn_Universe *universe, const nn_Filesystem *filesystem, nn_FilesystemHandler *handler, void *userdata) {
nn_Context ctx = universe->ctx; nn_Context ctx = universe->ctx;
nn_Filesystem_state *state = nn_alloc(&ctx, sizeof(*state)); nn_Filesystem_state *state = nn_alloc(&ctx, sizeof(*state));
if(state == NULL) return NULL; if(state == NULL) return NULL;
@@ -2611,7 +2611,7 @@ nn_ComponentType *nn_createFilesystem(nn_Universe *universe, const nn_Filesystem
{"makeDirectory", "function(path: string): boolean - Creates a directory. Creates parent directories if necessary.", NN_DIRECT}, {"makeDirectory", "function(path: string): boolean - Creates a directory. Creates parent directories if necessary.", NN_DIRECT},
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
}; };
nn_ComponentType *t = nn_createComponentType(universe, "filesystem", state, methods, nn_filesystem_handler); nn_ComponentState *t = nn_createComponentState(universe, "filesystem", state, methods, nn_filesystem_handler);
if(t == NULL) { if(t == NULL) {
nn_free(&ctx, state, sizeof(*state)); nn_free(&ctx, state, sizeof(*state));
return NULL; return NULL;
@@ -2688,7 +2688,7 @@ static nn_Exit nn_screen_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
} }
nn_ComponentType *nn_createScreen(nn_Universe *universe, nn_ScreenHandler *handler, void *userdata) { nn_ComponentState *nn_createScreen(nn_Universe *universe, nn_ScreenHandler *handler, void *userdata) {
nn_Context ctx = universe->ctx; nn_Context ctx = universe->ctx;
nn_Screen_state *state = nn_alloc(&ctx, sizeof(*state)); nn_Screen_state *state = nn_alloc(&ctx, sizeof(*state));
if(state == NULL) return NULL; if(state == NULL) return NULL;
@@ -2708,7 +2708,7 @@ nn_ComponentType *nn_createScreen(nn_Universe *universe, nn_ScreenHandler *handl
{"isTouchModeInverted", "function(): boolean - Checks if inverted touch mode is enabled.", NN_DIRECT}, {"isTouchModeInverted", "function(): boolean - Checks if inverted touch mode is enabled.", NN_DIRECT},
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
}; };
nn_ComponentType *t = nn_createComponentType(universe, "screen", state, methods, nn_screen_handler); nn_ComponentState *t = nn_createComponentState(universe, "screen", state, methods, nn_screen_handler);
if(t == NULL) { if(t == NULL) {
nn_free(&ctx, state, sizeof(*state)); nn_free(&ctx, state, sizeof(*state));
return NULL; return NULL;
@@ -2721,11 +2721,11 @@ static nn_Exit nn_keyboard_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
} }
nn_ComponentType *nn_createKeyboard(nn_Universe *universe) { nn_ComponentState *nn_createKeyboard(nn_Universe *universe) {
const nn_Method methods[] = { const nn_Method methods[] = {
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
}; };
return nn_createComponentType(universe, "keyboard", NULL, methods, nn_keyboard_handler); return nn_createComponentState(universe, "keyboard", NULL, methods, nn_keyboard_handler);
} }
nn_GPU nn_defaultGPUs[4] = { nn_GPU nn_defaultGPUs[4] = {
@@ -3080,7 +3080,7 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
} }
nn_ComponentType *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata) { nn_ComponentState *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata) {
nn_Context ctx = universe->ctx; nn_Context ctx = universe->ctx;
nn_GPU_state *state = nn_alloc(&ctx, sizeof(*state)); nn_GPU_state *state = nn_alloc(&ctx, sizeof(*state));
if(state == NULL) return NULL; if(state == NULL) return NULL;
@@ -3114,7 +3114,7 @@ nn_ComponentType *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUH
// TODO: vram buffers // TODO: vram buffers
{NULL, NULL, NN_INDIRECT}, {NULL, NULL, NN_INDIRECT},
}; };
nn_ComponentType *t = nn_createComponentType(universe, "gpu", state, methods, nn_gpu_handler); nn_ComponentState *t = nn_createComponentState(universe, "gpu", state, methods, nn_gpu_handler);
if(t == NULL) { if(t == NULL) {
nn_free(&ctx, state, sizeof(*state)); nn_free(&ctx, state, sizeof(*state));
return NULL; return NULL;

View File

@@ -461,7 +461,7 @@ typedef struct nn_Method {
nn_MethodFlags flags; nn_MethodFlags flags;
} nn_Method; } nn_Method;
typedef struct nn_ComponentType nn_ComponentType; typedef struct nn_ComponentState nn_ComponentState;
typedef enum nn_ComponentAction { typedef enum nn_ComponentAction {
// create the local state // create the local state
@@ -502,15 +502,15 @@ typedef struct nn_ComponentRequest {
typedef nn_Exit nn_ComponentHandler(nn_ComponentRequest *req); typedef nn_Exit nn_ComponentHandler(nn_ComponentRequest *req);
// Creates a new component type. It is safe to free name and methods afterwards. // Creates a new component type. It is safe to free name and methods afterwards.
nn_ComponentType *nn_createComponentType(nn_Universe *universe, const char *name, void *userdata, const nn_Method methods[], nn_ComponentHandler *handler); nn_ComponentState *nn_createComponentState(nn_Universe *universe, const char *name, void *userdata, const nn_Method methods[], nn_ComponentHandler *handler);
// NOTE: do not destroy this before destroying any components using it, or any computers with components using it. // NOTE: do not destroy this before destroying any components using it, or any computers with components using it.
// The component type is still used one last time for the destructor of the components. // The component type is still used one last time for the destructor of the components.
void nn_destroyComponentType(nn_ComponentType *ctype); void nn_destroyComponentState(nn_ComponentState *cstate);
// adds a component. Outside of the initialization state (aka after the first tick), it also emits the signal for component added. // adds a component. Outside of the initialization state (aka after the first tick), it also emits the signal for component added.
// You MUST NOT destroy the component type while a component using that type still exists. // You MUST NOT destroy the component type while a component using that type still exists.
// You can free the address after the call just fine. // You can free the address after the call just fine.
nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentType *ctype, const char *address, int slot, void *userdata); nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentState *cstate, const char *address, int slot, void *userdata);
// Checks if a component of that address exists. // Checks if a component of that address exists.
bool nn_hasComponent(nn_Computer *computer, const char *address); bool nn_hasComponent(nn_Computer *computer, const char *address);
// Checks if the component has that method. // Checks if the component has that method.
@@ -816,8 +816,8 @@ typedef nn_Exit nn_EEPROMHandler(nn_EEPROMRequest *request);
// the userdata passed to the component is the userdata // the userdata passed to the component is the userdata
// in the handler // in the handler
nn_ComponentType *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata); nn_ComponentState *nn_createEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, nn_EEPROMHandler *handler, void *userdata);
nn_ComponentType *nn_createVEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const nn_VEEPROM *vmem); nn_ComponentState *nn_createVEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const nn_VEEPROM *vmem);
// Note on paths: // Note on paths:
// - Paths given always have their length stored, but also have a NULL terminator. // - Paths given always have their length stored, but also have a NULL terminator.
@@ -976,7 +976,7 @@ extern nn_Filesystem nn_defaultFloppy;
typedef nn_Exit nn_FilesystemHandler(nn_FilesystemRequest *request); typedef nn_Exit nn_FilesystemHandler(nn_FilesystemRequest *request);
nn_ComponentType *nn_createFilesystem(nn_Universe *universe, const nn_Filesystem *filesystem, nn_FilesystemHandler *handler, void *userdata); nn_ComponentState *nn_createFilesystem(nn_Universe *universe, const nn_Filesystem *filesystem, nn_FilesystemHandler *handler, void *userdata);
typedef enum nn_ScreenAction { typedef enum nn_ScreenAction {
// instance dropped // instance dropped
@@ -1063,9 +1063,9 @@ extern nn_ScreenConfig nn_defaultScreens[4];
typedef nn_Exit nn_ScreenHandler(nn_ScreenRequest *req); typedef nn_Exit nn_ScreenHandler(nn_ScreenRequest *req);
nn_ComponentType *nn_createScreen(nn_Universe *universe, nn_ScreenHandler *handler, void *userdata); nn_ComponentState *nn_createScreen(nn_Universe *universe, nn_ScreenHandler *handler, void *userdata);
// a useless component which does nothing // a useless component which does nothing
nn_ComponentType *nn_createKeyboard(nn_Universe *universe); nn_ComponentState *nn_createKeyboard(nn_Universe *universe);
// Remember: // Remember:
// - Colors are in 0xRRGGBB format. // - Colors are in 0xRRGGBB format.
@@ -1269,7 +1269,7 @@ typedef nn_Exit nn_GPUHandler(nn_GPURequest *req);
// 1 GPU tier for every screen. // 1 GPU tier for every screen.
extern nn_GPU nn_defaultGPUs[4]; extern nn_GPU nn_defaultGPUs[4];
nn_ComponentType *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata); nn_ComponentState *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata);
// Colors and palettes. // Colors and palettes.
// Do note that the // Do note that the