Compare commits

...

6 Commits

Author SHA1 Message Date
IonutParau
6e58a20200 nn_intptr_t to nn_integer_t 2025-07-31 23:33:49 +02:00
IonutParau
f868465f88 yet another segfault fixed 2025-07-31 23:00:11 +02:00
IonutParau
6c30b81b9e oops 2025-07-31 22:57:48 +02:00
IonutParau
3cc5c162b4 oops, forgot something 2025-07-31 16:47:29 +02:00
IonutParau
fcd9b482f9 made it get compiled 2025-07-31 16:41:49 +02:00
IonutParau
a0bd37a213 progress on external computers 2025-07-31 16:41:04 +02:00
9 changed files with 223 additions and 23 deletions

View File

@ -45,6 +45,7 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
"src/components/tunnel.c",
"src/components/loopbackTunnel.c",
"src/components/diskDrive.c",
"src/components/externalComputer.c",
},
.flags = &.{
if(opts.baremetal) "-DNN_BAREMETAL" else "",

View File

@ -210,7 +210,7 @@ void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_co
nn_value offsetValue = nn_getArgument(computer, 0);
nn_value writeValue = nn_getArgument(computer, 1);
nn_size_t disk_offset = nn_toInt(offsetValue) - 1;
nn_intptr_t write = nn_toInt(writeValue);
nn_integer_t write = nn_toInt(writeValue);
nn_size_t sector_size = drive->table.sectorSize;
int sector = (disk_offset / sector_size) + 1;
nn_size_t sector_offset = disk_offset % sector_size;

View File

@ -0,0 +1,194 @@
#include "../neonucleus.h"
typedef struct nn_externalComputer_t {
nn_Context ctx;
nn_refc refc;
nn_guard *lock;
nn_externalComputerTable_t table;
} nn_externalComputer_t;
nn_externalComputer_t *nn_newExternalComputer(nn_Context *ctx, nn_externalComputerTable_t table) {
nn_externalComputer_t *external = nn_alloc(&ctx->allocator, sizeof(nn_externalComputer_t));
if(external == NULL) return NULL;
external->lock = nn_newGuard(ctx);
if(external->lock == NULL) {
nn_dealloc(&ctx->allocator, external, sizeof(nn_externalComputer_t));
return NULL;
}
external->refc = 1;
external->table = table;
return external;
}
nn_guard *nn_externalComputer_getLock(nn_externalComputer_t *external) {
return external->lock;
}
void nn_externalComputer_retain(nn_externalComputer_t *external) {
nn_incRef(&external->refc);
}
nn_bool_t nn_externalComputer_destroy(nn_externalComputer_t *external) {
if(!nn_decRef(&external->refc)) return false;
nn_Context ctx = external->ctx;
nn_deleteGuard(&ctx, external->lock);
nn_dealloc(&ctx.allocator, external, sizeof(nn_externalComputer_t));
return true;
}
void nni_externalComputer_componentDestroy(void *_, nn_component *component, nn_externalComputer_t *external) {
nn_externalComputer_destroy(external);
}
static void nni_externalComputer_start(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_lock(&external->ctx, external->lock);
nn_bool_t worked = external->table.start(external->table.userdata, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_setError(computer, err);
return;
}
nn_return_boolean(computer, worked);
}
static void nni_externalComputer_stop(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_lock(&external->ctx, external->lock);
nn_bool_t worked = external->table.stop(external->table.userdata, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_setError(computer, err);
return;
}
nn_return_boolean(computer, worked);
}
static void nni_externalComputer_isRunning(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_lock(&external->ctx, external->lock);
nn_bool_t truthy = external->table.isRunning(external->table.userdata, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_setError(computer, err);
return;
}
nn_return_boolean(computer, truthy);
}
static void nni_externalComputer_isRobot(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_lock(&external->ctx, external->lock);
nn_bool_t truthy = external->table.isRobot(external->table.userdata, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_setError(computer, err);
return;
}
nn_return_boolean(computer, truthy);
}
static void nni_externalComputer_getArchitecture(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_lock(&external->ctx, external->lock);
nn_architecture *arch = external->table.getArchitecture(external->table.userdata, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_setError(computer, err);
return;
}
nn_return_cstring(computer, arch->archName);
}
static void nni_externalComputer_getDeviceInfo(nn_externalComputer_t *external, void *_, nn_component *component, nn_computer *computer) {
nn_errorbuf_t err = "";
nn_deviceInfoList_t *info = nn_newDeviceInfoList(&external->ctx, 16);
if(info == NULL) {
nn_setCError(computer, "out of memory");
return;
}
nn_lock(&external->ctx, external->lock);
external->table.getDeviceInfo(external->table.userdata, info, computer, err);
nn_unlock(&external->ctx, external->lock);
if(!nn_error_isEmpty(err)) {
nn_deleteDeviceInfoList(info);
nn_setError(computer, err);
return;
}
nn_size_t deviceCount = nn_getDeviceCount(info);
nn_value devicesSerialized = nn_return_table(computer, deviceCount);
for(nn_size_t i = 0; i < deviceCount; i++) {
nn_deviceInfo_t *device = nn_getDeviceInfoAt(info, i);
nn_size_t deviceInfoSize = nn_getDeviceKeyCount(device);
nn_value deviceTable = nn_values_table(&external->ctx.allocator, deviceInfoSize);
for(nn_size_t j = 0; j < deviceInfoSize; j++) {
const char *value = NULL;
const char *key = nn_iterateDeviceInfoKeys(device, j, &value);
nn_values_setPair(
deviceTable,
j,
nn_values_string(&external->ctx.allocator, key, nn_strlen(key)),
nn_values_string(&external->ctx.allocator, value, nn_strlen(value))
);
}
const char *addr = nn_getDeviceInfoAddress(device);
nn_values_setPair(
devicesSerialized,
i,
nn_values_string(&external->ctx.allocator, addr, nn_strlen(addr)),
deviceTable
);
}
nn_deleteDeviceInfoList(info);
}
void nn_loadExternalComputerTable(nn_universe *universe) {
nn_componentTable *computerTable = nn_newComponentTable(nn_getAllocator(universe), "modem", NULL, NULL, (nn_componentDestructor *)nni_externalComputer_componentDestroy);
nn_storeUserdata(universe, "NN:COMPUTER", computerTable);
nn_method_t *method;
method = nn_defineMethod(computerTable, "start", (nn_componentMethod *)nni_externalComputer_start, "start(): boolean - Starts the computer. Returns whether it was successful");
nn_method_setDirect(method, false);
method = nn_defineMethod(computerTable, "stop", (nn_componentMethod *)nni_externalComputer_stop, "stop(): boolean - Stops the computer. Returns whether it was successful");
nn_method_setDirect(method, false);
method = nn_defineMethod(computerTable, "isRunning", (nn_componentMethod *)nni_externalComputer_isRunning, "isRunning(): boolean - Returns whether the computer was running");
nn_method_setDirect(method, false);
method = nn_defineMethod(computerTable, "isRobot", (nn_componentMethod *)nni_externalComputer_isRobot, "isRobot(): boolean - Returns whether the computer was running");
nn_method_setDirect(method, false);
method = nn_defineMethod(computerTable, "getArchitecture", (nn_componentMethod *)nni_externalComputer_getArchitecture, "getArchitecture(): string - Returns the name of the architecture of the computer");
nn_method_setDirect(method, false);
method = nn_defineMethod(computerTable, "getDeviceInfo", (nn_componentMethod *)nni_externalComputer_getDeviceInfo, "getDeviceList(): {[string]: {[string]: string}} - Returns information about the devices connected to the computer");
nn_method_setDirect(method, false);
}
nn_component *nn_externalComputer_addTo(nn_computer *computer, nn_address address, int slot, nn_externalComputer_t *external) {
nn_componentTable *computerTable = nn_queryUserdata(nn_getUniverse(computer), "NN:COMPUTER");
return nn_newComponent(computer, address, slot, computerTable, external);
}

View File

@ -103,7 +103,7 @@ static void nni_modem_setStrength(nn_modem *modem, void *_, nn_component *compon
nn_return_number(computer, n);
}
static nn_bool_t nni_modem_validSendPort(nn_intptr_t port) {
static nn_bool_t nni_modem_validSendPort(nn_integer_t port) {
// 9 quintillion ports just died
if(port < 0) return false;
// the only valid range
@ -115,7 +115,7 @@ static nn_bool_t nni_modem_validSendPort(nn_intptr_t port) {
}
static void nni_modem_isOpen(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) {
nn_intptr_t port = nn_toInt(nn_getArgument(computer, 0));
nn_integer_t port = nn_toInt(nn_getArgument(computer, 0));
if(!nni_modem_validSendPort(port)) {
nn_setCError(computer, "invalid port");
return;
@ -132,7 +132,7 @@ static void nni_modem_isOpen(nn_modem *modem, void *_, nn_component *component,
}
static void nni_modem_open(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) {
nn_intptr_t port = nn_toInt(nn_getArgument(computer, 0));
nn_integer_t port = nn_toInt(nn_getArgument(computer, 0));
if(!nni_modem_validSendPort(port)) {
nn_setCError(computer, "invalid port");
return;
@ -150,7 +150,7 @@ static void nni_modem_open(nn_modem *modem, void *_, nn_component *component, nn
static void nni_modem_close(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) {
nn_value portVal = nn_getArgument(computer, 0);
nn_intptr_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
nn_integer_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
if(!nni_modem_validSendPort(port) && port != NN_PORT_CLOSEALL) {
nn_setCError(computer, "invalid port");
return;
@ -191,7 +191,7 @@ static void nni_modem_send(nn_modem *modem, void *_, nn_component *component, nn
return;
}
nn_value portVal = nn_getArgument(computer, 1);
nn_intptr_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
nn_integer_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
if(!nni_modem_validSendPort(port) && port != NN_PORT_CLOSEALL) {
nn_setCError(computer, "invalid port");
return;
@ -232,7 +232,7 @@ static void nni_modem_send(nn_modem *modem, void *_, nn_component *component, nn
static void nni_modem_broadcast(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) {
nn_value portVal = nn_getArgument(computer, 0);
nn_intptr_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
nn_integer_t port = portVal.tag == NN_VALUE_NIL ? NN_PORT_CLOSEALL : nn_toInt(portVal);
if(!nni_modem_validSendPort(port) && port != NN_PORT_CLOSEALL) {
nn_setCError(computer, "invalid port");
return;

View File

@ -75,14 +75,10 @@ nn_bool_t nn_unsafeReallocateScreenBuffer(nn_screen *screen, int maxWidth, int m
}
for(nn_size_t y = 0; y < maxHeight; y++) {
if(y == screen->maxHeight) break;
for(nn_size_t x = 0; x < maxWidth; x++) {
if(x == screen->maxWidth) break;
nn_size_t srcIdx = x + y * screen->maxWidth;
nn_size_t destIdx = x + y * maxWidth;
newBuffer[destIdx] = screen->buffer[srcIdx];
newBuffer[destIdx] = nn_getPixel(screen, x, y);
}
}

View File

@ -28,7 +28,7 @@ typedef enum nn_vfmode {
typedef struct nn_vfhandle {
nn_vfnode *node;
nn_intptr_t position;
nn_integer_t position;
nn_vfmode mode;
} nn_vfhandle;
@ -539,7 +539,7 @@ nn_size_t nn_vfs_seek(nn_vfilesystem *fs, nn_vfhandle *handle, const char *whenc
nn_error_write(err, "Bad file descriptor");
return handle->node->len;
}
nn_intptr_t ptr = handle->position;
nn_integer_t ptr = handle->position;
if(nn_strcmp(whence, "set") == 0) {
ptr = off;
}

View File

@ -497,7 +497,7 @@ void nn_return_nil(nn_computer *computer) {
nn_return(computer, nn_values_nil());
}
void nn_return_integer(nn_computer *computer, nn_intptr_t integer) {
void nn_return_integer(nn_computer *computer, nn_integer_t integer) {
nn_return(computer, nn_values_integer(integer));
}

View File

@ -54,6 +54,8 @@ typedef unsigned char nn_bool_t;
#endif
typedef long long nn_integer_t;
// Based off https://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//define something for Windows (32-bit and 64-bit, this part is common)
@ -274,7 +276,7 @@ typedef struct nn_object {
typedef struct nn_value {
nn_size_t tag;
union {
nn_intptr_t integer;
nn_integer_t integer;
double number;
nn_bool_t boolean;
const char *cstring;
@ -633,7 +635,7 @@ nn_size_t nn_getReturnCount(nn_computer *computer);
// Value stuff
nn_value nn_values_nil(void);
nn_value nn_values_integer(nn_intptr_t integer);
nn_value nn_values_integer(nn_integer_t integer);
nn_value nn_values_number(double num);
nn_value nn_values_boolean(nn_bool_t boolean);
nn_value nn_values_cstring(const char *string);
@ -643,7 +645,7 @@ 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_integer(nn_computer *computer, nn_intptr_t integer);
void nn_return_integer(nn_computer *computer, nn_integer_t integer);
void nn_return_number(nn_computer *computer, double number);
void nn_return_boolean(nn_computer *computer, nn_bool_t boolean);
void nn_return_cstring(nn_computer *computer, const char *cstr);
@ -663,13 +665,13 @@ nn_value nn_values_get(nn_value arr, nn_size_t idx);
void nn_values_setPair(nn_value obj, nn_size_t idx, nn_value key, nn_value val);
nn_pair nn_values_getPair(nn_value obj, nn_size_t idx);
nn_intptr_t nn_toInt(nn_value val);
nn_integer_t nn_toInt(nn_value val);
double nn_toNumber(nn_value val);
nn_bool_t nn_toBoolean(nn_value val);
const char *nn_toCString(nn_value val);
const char *nn_toString(nn_value val, nn_size_t *len);
nn_intptr_t nn_toIntOr(nn_value val, nn_intptr_t defaultVal);
nn_integer_t nn_toIntOr(nn_value val, nn_integer_t defaultVal);
double nn_toNumberOr(nn_value val, double defaultVal);
nn_bool_t nn_toBooleanOr(nn_value val, nn_bool_t defaultVal);
@ -694,6 +696,7 @@ void nn_loadKeyboardTable(nn_universe *universe);
void nn_loadModemTable(nn_universe *universe);
void nn_loadTunnelTable(nn_universe *universe);
void nn_loadDiskDriveTable(nn_universe *universe);
void nn_loadExternalComputerTable(nn_universe *universe);
nn_component *nn_mountKeyboard(nn_computer *computer, nn_address address, int slot);
@ -1136,6 +1139,7 @@ typedef struct nn_externalComputerTable_t {
void (*beep)(void *userdata, nn_computer *requester, double freq, double duration, double volume, nn_errorbuf_t err);
void (*crash)(void *userdata, nn_computer *requester, nn_errorbuf_t err);
nn_architecture *(*getArchitecture)(void *userdata, nn_computer *requester, nn_errorbuf_t err);
void (*getDeviceInfo)(void *userdata, nn_deviceInfoList_t *list, nn_computer *requester, nn_errorbuf_t err);
nn_bool_t (*isRobot)(void *userdata, nn_computer *requester, nn_errorbuf_t err);
} nn_externalComputerTable_t;
@ -1145,6 +1149,11 @@ typedef struct nn_externalComputer_t nn_externalComputer_t;
// It may refer to the current computer (counter-intuitively)
// It may exist when the computer it is refering too has no running state (aka is powered off)
nn_externalComputer_t *nn_newExternalComputer(nn_Context *ctx, nn_externalComputerTable_t table);
nn_guard *nn_externalComputer_getLock(nn_externalComputer_t *external);
void nn_externalComputer_retain(nn_externalComputer_t *external);
nn_bool_t nn_externalComputer_destroy(nn_externalComputer_t *external);
nn_component *nn_externalComputer_addTo(nn_computer *computer, nn_address address, int slot, nn_externalComputer_t *external);
#ifdef __cplusplus // c++ sucks
}

View File

@ -4,7 +4,7 @@ nn_value nn_values_nil(void) {
return (nn_value) {.tag = NN_VALUE_NIL};
}
nn_value nn_values_integer(nn_intptr_t integer) {
nn_value nn_values_integer(nn_integer_t integer) {
return (nn_value) {.tag = NN_VALUE_INT, .integer = integer};
}
@ -171,7 +171,7 @@ nn_pair nn_values_getPair(nn_value obj, nn_size_t idx) {
return obj.table->pairs[idx];
}
nn_intptr_t nn_toInt(nn_value val) {
nn_integer_t nn_toInt(nn_value val) {
if(val.tag == NN_VALUE_INT) return val.integer;
if(val.tag == NN_VALUE_NUMBER) return val.number;
return 0;
@ -212,7 +212,7 @@ const char *nn_toString(nn_value val, nn_size_t *len) {
return c;
}
nn_intptr_t nn_toIntOr(nn_value val, nn_intptr_t defaultVal) {
nn_integer_t nn_toIntOr(nn_value val, nn_integer_t defaultVal) {
if(val.tag == NN_VALUE_INT) return val.integer;
if(val.tag == NN_VALUE_NUMBER) return val.number;
return defaultVal;