mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
disk drives and resources
This commit is contained in:
parent
3f873f5165
commit
0c3a3f0d75
@ -24,6 +24,7 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
|
|||||||
"src/lock.c",
|
"src/lock.c",
|
||||||
"src/utils.c",
|
"src/utils.c",
|
||||||
"src/value.c",
|
"src/value.c",
|
||||||
|
"src/resource.c",
|
||||||
"src/component.c",
|
"src/component.c",
|
||||||
"src/computer.c",
|
"src/computer.c",
|
||||||
"src/universe.c",
|
"src/universe.c",
|
||||||
@ -40,6 +41,7 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
|
|||||||
"src/components/keyboard.c",
|
"src/components/keyboard.c",
|
||||||
"src/components/modem.c",
|
"src/components/modem.c",
|
||||||
"src/components/loopbackModem.c",
|
"src/components/loopbackModem.c",
|
||||||
|
"src/components/diskDrive.c",
|
||||||
},
|
},
|
||||||
.flags = &.{
|
.flags = &.{
|
||||||
if(opts.baremetal) "-DNN_BAREMETAL" else "",
|
if(opts.baremetal) "-DNN_BAREMETAL" else "",
|
||||||
@ -178,7 +180,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
emulator.linkLibrary(raylib.artifact("raylib"));
|
emulator.linkLibrary(raylib.artifact("raylib"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const luaVer = b.option(LuaVersion, "lua", "The version of Lua to use.") orelse LuaVersion.lua52;
|
const luaVer = b.option(LuaVersion, "lua", "The version of Lua to use.") orelse LuaVersion.lua53;
|
||||||
emulator.addCSourceFiles(.{
|
emulator.addCSourceFiles(.{
|
||||||
.files = &.{
|
.files = &.{
|
||||||
"src/testLuaArch.c",
|
"src/testLuaArch.c",
|
||||||
|
112
src/components/diskDrive.c
Normal file
112
src/components/diskDrive.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include "../neonucleus.h"
|
||||||
|
|
||||||
|
typedef struct nn_diskDrive {
|
||||||
|
nn_Context ctx;
|
||||||
|
nn_guard *lock;
|
||||||
|
nn_refc refc;
|
||||||
|
nn_diskDriveTable table;
|
||||||
|
} nn_diskDrive;
|
||||||
|
|
||||||
|
nn_diskDrive *nn_newDiskDrive(nn_Context *context, nn_diskDriveTable table) {
|
||||||
|
nn_diskDrive *drive = nn_alloc(&context->allocator, sizeof(nn_diskDrive));
|
||||||
|
if(drive == NULL) return NULL;
|
||||||
|
drive->lock = nn_newGuard(context);
|
||||||
|
if(drive->lock == NULL) {
|
||||||
|
nn_dealloc(&context->allocator, drive, sizeof(nn_diskDrive));
|
||||||
|
}
|
||||||
|
drive->refc = 1;
|
||||||
|
drive->table = table;
|
||||||
|
drive->ctx = *context;
|
||||||
|
return drive;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_guard *nn_getDiskDriveLock(nn_diskDrive *diskDrive) {
|
||||||
|
return diskDrive->lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_retainDiskDrive(nn_diskDrive *diskDrive) {
|
||||||
|
nn_incRef(&diskDrive->refc);
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_bool_t nn_destroyDiskDrive(nn_diskDrive *diskDrive) {
|
||||||
|
if(!nn_decRef(&diskDrive->refc)) return false;
|
||||||
|
if(diskDrive->table.deinit != NULL) {
|
||||||
|
diskDrive->table.deinit(diskDrive->table.userdata);
|
||||||
|
}
|
||||||
|
nn_Context ctx = diskDrive->ctx;
|
||||||
|
nn_Alloc a = ctx.allocator;
|
||||||
|
|
||||||
|
nn_deleteGuard(&ctx, diskDrive->lock);
|
||||||
|
nn_dealloc(&a, diskDrive, sizeof(nn_diskDrive));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_diskDrive_destroy(void *_, nn_component *component, nn_diskDrive *diskDrive) {
|
||||||
|
nn_destroyDiskDrive(diskDrive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_diskDrive_eject(nn_diskDrive *diskDrive, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
double velocity = nn_toNumberOr(nn_getArgument(computer, 0), 0);
|
||||||
|
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
nn_lock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
if(diskDrive->table.isEmpty(diskDrive->table.userdata)) {
|
||||||
|
nn_unlock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
nn_return_boolean(computer, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diskDrive->table.eject(diskDrive->table.userdata, velocity, err);
|
||||||
|
nn_unlock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_return_boolean(computer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_diskDrive_isEmpty(nn_diskDrive *diskDrive, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_lock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
nn_bool_t empty = diskDrive->table.isEmpty(diskDrive->table.userdata);
|
||||||
|
nn_unlock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
|
||||||
|
nn_return_boolean(computer, empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_diskDrive_media(nn_diskDrive *diskDrive, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
nn_Alloc *a = &diskDrive->ctx.allocator;
|
||||||
|
nn_lock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
if(diskDrive->table.isEmpty(diskDrive->table.userdata)) {
|
||||||
|
nn_unlock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
nn_setCError(computer, "drive is empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nn_address s = diskDrive->table.media(diskDrive->table.userdata, a, err);
|
||||||
|
nn_unlock(&diskDrive->ctx, diskDrive->lock);
|
||||||
|
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_deallocStr(a, s);
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_return_string(computer, s, nn_strlen(s));
|
||||||
|
nn_deallocStr(a, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_loadDiskDriveTable(nn_universe *universe) {
|
||||||
|
nn_componentTable *diskDriveTable = nn_newComponentTable(nn_getAllocator(universe), "disk_drive", NULL, NULL, (void *)nn_diskDrive_destroy);
|
||||||
|
nn_storeUserdata(universe, "NN:DISK_DRIVE", diskDriveTable);
|
||||||
|
|
||||||
|
nn_defineMethod(diskDriveTable, "eject", (nn_componentMethod *)nn_diskDrive_eject, "eject([velocity: number]): boolean - Ejects the floopy, if present. Returns whether it was present.");
|
||||||
|
nn_defineMethod(diskDriveTable, "isEmpty", (nn_componentMethod *)nn_diskDrive_isEmpty, "isEmpty(): boolean - Returns whether the drive is empty.");
|
||||||
|
nn_defineMethod(diskDriveTable, "media", (nn_componentMethod *)nn_diskDrive_media, "media(): string - Returns the address of the inner floppy disk.");
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_component *nn_addDiskDrive(nn_computer *computer, nn_address address, int slot, nn_diskDrive *diskDrive) {
|
||||||
|
nn_componentTable *diskDriveTable = nn_queryUserdata(nn_getUniverse(computer), "NN:DISK_DRIVE");
|
||||||
|
|
||||||
|
return nn_newComponent(computer, address, slot, diskDriveTable, diskDrive);
|
||||||
|
}
|
@ -220,6 +220,7 @@ nni_gpu *nni_newGPU(nn_Alloc *alloc, nn_gpuControl *ctrl) {
|
|||||||
for(int i = 0; i < ctrl->maximumBufferCount; i++) {
|
for(int i = 0; i < ctrl->maximumBufferCount; i++) {
|
||||||
gpu->buffers[i] = NULL;
|
gpu->buffers[i] = NULL;
|
||||||
}
|
}
|
||||||
|
gpu->activeBuffer = 0;
|
||||||
gpu->usedVRAM = 0;
|
gpu->usedVRAM = 0;
|
||||||
return gpu;
|
return gpu;
|
||||||
}
|
}
|
||||||
@ -320,7 +321,6 @@ void nni_gpu_set(nni_gpu *gpu, void *_, nn_component *component, nn_computer *co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(gpu->activeBuffer != 0) {
|
if(gpu->activeBuffer != 0) {
|
||||||
nni_buffer *buffer = gpu->buffers[gpu->activeBuffer - 1];
|
|
||||||
nni_vram_set(gpu, x, y, s, isVertical);
|
nni_vram_set(gpu, x, y, s, isVertical);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "component.h"
|
#include "component.h"
|
||||||
#include "universe.h"
|
#include "universe.h"
|
||||||
#include "neonucleus.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_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;
|
nn_Alloc *alloc = &universe->ctx.allocator;
|
||||||
@ -58,6 +59,11 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
|
|||||||
return NULL;
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +141,11 @@ void nn_deleteComputer(nn_computer *computer) {
|
|||||||
for(nn_size_t i = 0; i < computer->userCount; i++) {
|
for(nn_size_t i = 0; i < computer->userCount; i++) {
|
||||||
nn_deallocStr(a, computer->users[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);
|
computer->arch->teardown(computer, computer->archState, computer->arch->userdata);
|
||||||
nn_deleteGuard(&computer->universe->ctx, computer->lock);
|
nn_deleteGuard(&computer->universe->ctx, computer->lock);
|
||||||
nn_deallocStr(a, computer->address);
|
nn_deallocStr(a, computer->address);
|
||||||
@ -524,6 +535,10 @@ nn_value nn_return_table(nn_computer *computer, nn_size_t len) {
|
|||||||
return val;
|
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) {
|
nn_bool_t nn_wakeupMatches(nn_value *values, nn_size_t valueLen, const char *wakeUp, nn_bool_t fuzzy) {
|
||||||
if(valueLen == 0) return false;
|
if(valueLen == 0) return false;
|
||||||
nn_value header = values[0];
|
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);
|
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;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,12 @@ typedef struct nn_signal {
|
|||||||
nn_value values[NN_MAX_SIGNAL_VALS];
|
nn_value values[NN_MAX_SIGNAL_VALS];
|
||||||
} nn_signal;
|
} nn_signal;
|
||||||
|
|
||||||
|
typedef struct nn_resource_t {
|
||||||
|
size_t id;
|
||||||
|
void *ptr;
|
||||||
|
nn_resourceTable_t *table;
|
||||||
|
} nn_resource_t;
|
||||||
|
|
||||||
typedef struct nn_computer {
|
typedef struct nn_computer {
|
||||||
char state;
|
char state;
|
||||||
nn_bool_t allocatedError;
|
nn_bool_t allocatedError;
|
||||||
@ -21,7 +27,7 @@ typedef struct nn_computer {
|
|||||||
nn_size_t argc;
|
nn_size_t argc;
|
||||||
nn_value rets[NN_MAX_RETS];
|
nn_value rets[NN_MAX_RETS];
|
||||||
nn_size_t retc;
|
nn_size_t retc;
|
||||||
nn_architecture *arch;
|
nn_architecture *arch; // btw
|
||||||
void *archState;
|
void *archState;
|
||||||
nn_architecture *nextArch;
|
nn_architecture *nextArch;
|
||||||
nn_architecture *supportedArch[NN_MAX_ARCHITECTURES];
|
nn_architecture *supportedArch[NN_MAX_ARCHITECTURES];
|
||||||
@ -42,6 +48,8 @@ typedef struct nn_computer {
|
|||||||
double roomTemperature;
|
double roomTemperature;
|
||||||
double callCost;
|
double callCost;
|
||||||
double callBudget;
|
double callBudget;
|
||||||
|
nn_size_t rid;
|
||||||
|
nn_resource_t resources[NN_MAX_CONCURRENT_RESOURCES];
|
||||||
} nn_computer;
|
} nn_computer;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,6 +119,8 @@ extern "C" {
|
|||||||
#define NN_MAX_CHANNEL_SIZE 256
|
#define NN_MAX_CHANNEL_SIZE 256
|
||||||
#define NN_TUNNEL_PORT 0
|
#define NN_TUNNEL_PORT 0
|
||||||
#define NN_PORT_CLOSEALL 0
|
#define NN_PORT_CLOSEALL 0
|
||||||
|
#define NN_MAX_CONCURRENT_RESOURCES 64
|
||||||
|
#define NN_NULL_RESOURCE 0
|
||||||
|
|
||||||
#define NN_OVERHEAT_MIN 100
|
#define NN_OVERHEAT_MIN 100
|
||||||
#define NN_CALL_HEAT 0.05
|
#define NN_CALL_HEAT 0.05
|
||||||
@ -243,6 +245,7 @@ void nn_error_clear(nn_errorbuf_t buf);
|
|||||||
#define NN_VALUE_ARRAY 5
|
#define NN_VALUE_ARRAY 5
|
||||||
#define NN_VALUE_TABLE 6
|
#define NN_VALUE_TABLE 6
|
||||||
#define NN_VALUE_NIL 7
|
#define NN_VALUE_NIL 7
|
||||||
|
#define NN_VALUE_RESOURCE 8
|
||||||
|
|
||||||
typedef struct nn_string {
|
typedef struct nn_string {
|
||||||
char *data;
|
char *data;
|
||||||
@ -275,6 +278,7 @@ typedef struct nn_value {
|
|||||||
nn_string *string;
|
nn_string *string;
|
||||||
nn_array *array;
|
nn_array *array;
|
||||||
nn_table *table;
|
nn_table *table;
|
||||||
|
nn_size_t resourceID;
|
||||||
};
|
};
|
||||||
} nn_value;
|
} nn_value;
|
||||||
|
|
||||||
@ -542,6 +546,27 @@ const char *nn_getTableMethod(nn_componentTable *table, nn_size_t idx, nn_bool_t
|
|||||||
const char *nn_methodDoc(nn_componentTable *table, const char *methodName);
|
const char *nn_methodDoc(nn_componentTable *table, const char *methodName);
|
||||||
nn_bool_t nn_isMethodEnabled(nn_component *component, const char *methodName);
|
nn_bool_t nn_isMethodEnabled(nn_component *component, const char *methodName);
|
||||||
|
|
||||||
|
// Resource stuff
|
||||||
|
|
||||||
|
typedef struct nn_resourceTable_t nn_resourceTable_t;
|
||||||
|
typedef struct nn_resourceMethod_t nn_resourceMethod_t;
|
||||||
|
|
||||||
|
typedef void nn_resourceDestructor_t(void *userdata);
|
||||||
|
typedef void nn_resourceMethodCallback_t(void *userdata, void *methodUserdata, nn_computer *computer);
|
||||||
|
typedef nn_bool_t nn_resourceMethodCondition_t(void *userdata, void *methodUserdata);
|
||||||
|
|
||||||
|
nn_resourceTable_t *nn_resource_newTable(nn_Context *ctx, nn_resourceDestructor_t *dtor);
|
||||||
|
nn_resourceMethod_t *nn_resource_addMethod(nn_resourceTable_t *table, const char *methodName, nn_resourceMethodCallback_t *method, const char *doc);
|
||||||
|
void nn_resource_setUserdata(nn_resourceMethod_t *method, void *methodUserdata);
|
||||||
|
void nn_resource_setCondition(nn_resourceMethod_t *method, nn_resourceMethodCondition_t *methodCondition);
|
||||||
|
nn_bool_t nn_resource_invoke(nn_computer *computer, nn_size_t resourceID, const char *method);
|
||||||
|
// 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_resourceTable_t *nn_resource_fetchTable(nn_computer *computer, nn_size_t resourceID);
|
||||||
|
nn_size_t nn_resource_allocate(nn_computer *computer, void *userdata, nn_resourceTable_t *table);
|
||||||
|
void nn_resource_release(nn_computer *computer, nn_size_t id);
|
||||||
|
|
||||||
// Component calling
|
// Component calling
|
||||||
|
|
||||||
/* Returns false if the method does not exist */
|
/* Returns false if the method does not exist */
|
||||||
@ -565,6 +590,7 @@ nn_value nn_values_cstring(const char *string);
|
|||||||
nn_value nn_values_string(nn_Alloc *alloc, const char *string, nn_size_t len);
|
nn_value nn_values_string(nn_Alloc *alloc, const char *string, nn_size_t len);
|
||||||
nn_value nn_values_array(nn_Alloc *alloc, nn_size_t len);
|
nn_value nn_values_array(nn_Alloc *alloc, nn_size_t len);
|
||||||
nn_value nn_values_table(nn_Alloc *alloc, nn_size_t pairCount);
|
nn_value nn_values_table(nn_Alloc *alloc, nn_size_t pairCount);
|
||||||
|
nn_value nn_values_resource(nn_size_t id);
|
||||||
|
|
||||||
void nn_return_nil(nn_computer *computer);
|
void nn_return_nil(nn_computer *computer);
|
||||||
void nn_return_integer(nn_computer *computer, nn_intptr_t integer);
|
void nn_return_integer(nn_computer *computer, nn_intptr_t integer);
|
||||||
@ -574,6 +600,7 @@ void nn_return_cstring(nn_computer *computer, const char *cstr);
|
|||||||
void nn_return_string(nn_computer *computer, const char *str, nn_size_t len);
|
void nn_return_string(nn_computer *computer, const char *str, nn_size_t len);
|
||||||
nn_value nn_return_array(nn_computer *computer, nn_size_t len);
|
nn_value nn_return_array(nn_computer *computer, nn_size_t len);
|
||||||
nn_value nn_return_table(nn_computer *computer, nn_size_t len);
|
nn_value nn_return_table(nn_computer *computer, nn_size_t len);
|
||||||
|
void nn_return_resource(nn_computer *computer, nn_size_t userdata);
|
||||||
|
|
||||||
nn_size_t nn_values_getType(nn_value val);
|
nn_size_t nn_values_getType(nn_value val);
|
||||||
nn_value nn_values_retain(nn_value val);
|
nn_value nn_values_retain(nn_value val);
|
||||||
@ -616,6 +643,7 @@ void nn_loadGraphicsCardTable(nn_universe *universe);
|
|||||||
void nn_loadKeyboardTable(nn_universe *universe);
|
void nn_loadKeyboardTable(nn_universe *universe);
|
||||||
void nn_loadModemTable(nn_universe *universe);
|
void nn_loadModemTable(nn_universe *universe);
|
||||||
void nn_loadTunnelTable(nn_universe *universe);
|
void nn_loadTunnelTable(nn_universe *universe);
|
||||||
|
void nn_loadDiskDriveTable(nn_universe *universe);
|
||||||
|
|
||||||
nn_component *nn_mountKeyboard(nn_computer *computer, nn_address address, int slot);
|
nn_component *nn_mountKeyboard(nn_computer *computer, nn_address address, int slot);
|
||||||
|
|
||||||
@ -998,7 +1026,26 @@ nn_guard *nn_getTunnelLock(nn_tunnel *tunnel);
|
|||||||
void nn_retainTunnel(nn_tunnel *tunnel);
|
void nn_retainTunnel(nn_tunnel *tunnel);
|
||||||
nn_bool_t nn_destroyTunnel(nn_tunnel *tunnel);
|
nn_bool_t nn_destroyTunnel(nn_tunnel *tunnel);
|
||||||
|
|
||||||
nn_component *nn_addTunnel(nn_computer *computer, nn_address address, int slot, nn_tunnel *modem);
|
nn_component *nn_addTunnel(nn_computer *computer, nn_address address, int slot, nn_tunnel *tunnel);
|
||||||
|
|
||||||
|
typedef struct nn_diskDriveTable {
|
||||||
|
void *userdata;
|
||||||
|
void (*deinit)(void *userdata);
|
||||||
|
|
||||||
|
// velocity is 0 or less for "default"
|
||||||
|
void (*eject)(void *userdata, double velocity, nn_errorbuf_t err);
|
||||||
|
nn_bool_t (*isEmpty)(void *userdata);
|
||||||
|
nn_address (*media)(void *userdata, nn_Alloc *alloc, nn_errorbuf_t err);
|
||||||
|
} nn_diskDriveTable;
|
||||||
|
|
||||||
|
typedef struct nn_diskDrive nn_diskDrive;
|
||||||
|
|
||||||
|
nn_diskDrive *nn_newDiskDrive(nn_Context *context, nn_diskDriveTable table);
|
||||||
|
nn_guard *nn_getDiskDriveLock(nn_diskDrive *diskDrive);
|
||||||
|
void nn_retainDiskDrive(nn_diskDrive *diskDrive);
|
||||||
|
nn_bool_t nn_destroyDiskDrive(nn_diskDrive *diskDrive);
|
||||||
|
|
||||||
|
nn_component *nn_addDiskDrive(nn_computer *computer, nn_address address, int slot, nn_diskDrive *diskDrive);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
29
src/resource.c
Normal file
29
src/resource.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
nn_resourceTable_t *nn_resource_newTable(nn_Context *ctx, nn_resourceDestructor_t *dtor) {
|
||||||
|
nn_resourceTable_t *t = nn_alloc(&ctx->allocator, sizeof(nn_resourceTable_t));
|
||||||
|
if(t == NULL) return NULL;
|
||||||
|
t->dtor = dtor;
|
||||||
|
t->methodCount = 0;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_resourceMethod_t *nn_resource_addMethod(nn_resourceTable_t *table, const char *methodName, nn_resourceMethodCallback_t *method, const char *doc) {
|
||||||
|
if(table->methodCount == NN_MAX_METHODS) return NULL;
|
||||||
|
nn_resourceMethod_t *m = &table->methods[table->methodCount];
|
||||||
|
table->methodCount++;
|
||||||
|
nn_Alloc *a = &table->ctx.allocator;
|
||||||
|
m->name = nn_strdup(a, methodName);
|
||||||
|
m->doc = nn_strdup(a, doc);
|
||||||
|
m->callback = method;
|
||||||
|
m->condition = NULL;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_resource_setUserdata(nn_resourceMethod_t *method, void *methodUserdata) {
|
||||||
|
method->userdata = methodUserdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_resource_setCondition(nn_resourceMethod_t *method, nn_resourceMethodCondition_t *methodCondition) {
|
||||||
|
method->condition = methodCondition;
|
||||||
|
}
|
21
src/resource.h
Normal file
21
src/resource.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef NN_RESOURCE
|
||||||
|
#define NN_RESOURCE
|
||||||
|
|
||||||
|
#include "neonucleus.h"
|
||||||
|
|
||||||
|
typedef struct nn_resourceMethod_t {
|
||||||
|
const char *name;
|
||||||
|
const char *doc;
|
||||||
|
void *userdata;
|
||||||
|
nn_resourceMethodCallback_t *callback;
|
||||||
|
nn_resourceMethodCondition_t *condition;
|
||||||
|
} nn_resourceMethod_t;
|
||||||
|
|
||||||
|
typedef struct nn_resourceTable_t {
|
||||||
|
nn_Context ctx;
|
||||||
|
nn_resourceDestructor_t *dtor;
|
||||||
|
nn_size_t methodCount;
|
||||||
|
nn_resourceMethod_t methods[NN_MAX_METHODS];
|
||||||
|
} nn_resourceTable_t;
|
||||||
|
|
||||||
|
#endif
|
@ -160,6 +160,7 @@ static void testLuaArch_pushValue(lua_State *L, nn_value val) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
luaL_error(L, "invalid return type: %d", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int testLuaArch_computer_clearError(lua_State *L) {
|
static int testLuaArch_computer_clearError(lua_State *L) {
|
||||||
|
@ -54,4 +54,5 @@ void nn_loadCoreComponentTables(nn_universe *universe) {
|
|||||||
nn_loadGraphicsCardTable(universe);
|
nn_loadGraphicsCardTable(universe);
|
||||||
nn_loadKeyboardTable(universe);
|
nn_loadKeyboardTable(universe);
|
||||||
nn_loadModemTable(universe);
|
nn_loadModemTable(universe);
|
||||||
|
nn_loadDiskDriveTable(universe);
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,13 @@ nn_value nn_values_table(nn_Alloc *alloc, nn_size_t pairCount) {
|
|||||||
return (nn_value) {.tag = NN_VALUE_TABLE, .table = table};
|
return (nn_value) {.tag = NN_VALUE_TABLE, .table = table};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nn_value nn_values_resource(nn_size_t id) {
|
||||||
|
return (nn_value) {
|
||||||
|
.tag = NN_VALUE_RESOURCE,
|
||||||
|
.resourceID = id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
nn_size_t nn_values_getType(nn_value val) {
|
nn_size_t nn_values_getType(nn_value val) {
|
||||||
return val.tag;
|
return val.tag;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user