disk drives and resources

This commit is contained in:
2025-07-25 18:10:16 +02:00
parent 3f873f5165
commit 0c3a3f0d75
11 changed files with 327 additions and 4 deletions

View File

@@ -2,6 +2,7 @@
#include "component.h"
#include "universe.h"
#include "neonucleus.h"
#include "resource.h"
nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, nn_size_t memoryLimit, nn_size_t componentLimit) {
nn_Alloc *alloc = &universe->ctx.allocator;
@@ -58,6 +59,11 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
return NULL;
}
c->rid = NN_NULL_RESOURCE;
for(nn_size_t i = 0; i < NN_MAX_CONCURRENT_RESOURCES; i++) {
c->resources[i].id = NN_NULL_RESOURCE;
}
return c;
}
@@ -135,6 +141,11 @@ void nn_deleteComputer(nn_computer *computer) {
for(nn_size_t i = 0; i < computer->userCount; i++) {
nn_deallocStr(a, computer->users[i]);
}
for(nn_size_t i = 0; i < NN_MAX_CONCURRENT_RESOURCES; i++) {
if(computer->resources[i].id != NN_NULL_RESOURCE) {
nn_resource_release(computer, computer->resources[i].id);
}
}
computer->arch->teardown(computer, computer->archState, computer->arch->userdata);
nn_deleteGuard(&computer->universe->ctx, computer->lock);
nn_deallocStr(a, computer->address);
@@ -524,6 +535,10 @@ nn_value nn_return_table(nn_computer *computer, nn_size_t len) {
return val;
}
void nn_return_resource(nn_computer *computer, nn_size_t userdata) {
nn_return(computer, nn_values_resource(userdata));
}
nn_bool_t nn_wakeupMatches(nn_value *values, nn_size_t valueLen, const char *wakeUp, nn_bool_t fuzzy) {
if(valueLen == 0) return false;
nn_value header = values[0];
@@ -551,3 +566,83 @@ const char *nn_pushNetworkMessage(nn_computer *computer, nn_address receiver, nn
return nn_pushSignal(computer, buffer, valueLen + 5);
}
static nn_resource_t *nn_resource_find(nn_computer *computer, nn_size_t id) {
for(nn_size_t i = 0; i < NN_MAX_CONCURRENT_RESOURCES; i++) {
if(computer->resources[i].id == id) {
return computer->resources + i;
}
}
return NULL;
}
nn_size_t nn_resource_allocate(nn_computer *computer, void *userdata, nn_resourceTable_t *table) {
nn_size_t i = 0;
for(nn_size_t j = 0; j < NN_MAX_CONCURRENT_RESOURCES; j++) {
if(computer->resources[j].id == NN_NULL_RESOURCE) {
i = j;
goto slotFound;
}
}
return NN_NULL_RESOURCE;
slotFound:
computer->rid++;
nn_size_t rid = computer->rid;
computer->resources[i] = (nn_resource_t) {
.id = rid,
.ptr = userdata,
.table = table,
};
return rid;
}
void nn_resource_release(nn_computer *computer, nn_size_t id) {
nn_resource_t *res = nn_resource_find(computer, id);
if(res == NULL) return;
res->id = NN_NULL_RESOURCE;
if(res->table->dtor != NULL) {
res->table->dtor(res->ptr);
}
}
nn_resourceTable_t *nn_resource_fetchTable(nn_computer *computer, nn_size_t resourceID) {
nn_resource_t *res = nn_resource_find(computer, resourceID);
if(res == NULL) return NULL;
return res->table;
}
nn_bool_t nn_resource_invoke(nn_computer *computer, nn_size_t resourceID, const char *method) {
nn_resource_t *res = nn_resource_find(computer, resourceID);
if(res == NULL) return false;
nn_resourceTable_t *t = res->table;
for(nn_size_t i = 0; i < t->methodCount; i++) {
nn_resourceMethod_t m = t->methods[i];
if(nn_strcmp(m.name, method) != 0) continue;
if(m.condition != NULL) {
if(!m.condition(res->ptr, m.userdata)) continue;
}
m.callback(res->ptr, m.userdata, computer);
return true;
}
return false;
}
// returns the name, and NULL for out of bounds
const char *nn_resource_nextMethodInfo(nn_computer *computer, nn_size_t id, const char **doc, nn_size_t *idx) {
nn_resource_t *res = nn_resource_find(computer, id);
if(res == NULL) return false;
nn_resourceTable_t *t = res->table;
for(nn_size_t i = *idx; i < t->methodCount; i++) {
nn_resourceMethod_t method = t->methods[i];
if(method.condition != NULL) {
if(!method.condition(res->ptr, method.userdata)) {
continue;
}
}
*idx = i + 1;
*doc = method.doc;
return method.name;
}
return NULL;
}