mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
Compare commits
6 Commits
cab0106a6a
...
6e58a20200
Author | SHA1 | Date | |
---|---|---|---|
|
6e58a20200 | ||
|
f868465f88 | ||
|
6c30b81b9e | ||
|
3cc5c162b4 | ||
|
fcd9b482f9 | ||
|
a0bd37a213 |
@ -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 "",
|
||||
|
@ -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;
|
||||
|
194
src/components/externalComputer.c
Normal file
194
src/components/externalComputer.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user