modem methods
This commit is contained in:
29
TODO.md
29
TODO.md
@@ -1,12 +1,11 @@
|
|||||||
# For MVP functionality
|
# To improve the API
|
||||||
|
|
||||||
- make `computer` component use callbacks
|
|
||||||
- finish tmpfs (rework the whole thing)
|
- finish tmpfs (rework the whole thing)
|
||||||
|
|
||||||
# To re-evaluate
|
# To re-evaluate
|
||||||
|
|
||||||
- Exposing the internal non-resizing hashmap implementation.
|
- Make the hashmap growing/shrinking to save on memory.
|
||||||
- More stack manipulation functions to allow libraries to have better APIs. (rotate)
|
- Exposing the internal hashmap implementation.
|
||||||
- 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.
|
||||||
- Exposing more internal functions that may be useful to the user to prevent pointless rewriting and duplicate machine code.
|
- Exposing more internal functions that may be useful to the user to prevent pointless rewriting and duplicate machine code.
|
||||||
@@ -15,12 +14,11 @@ to be made more portable.
|
|||||||
|
|
||||||
Not everything OC has (as a few of them are really MC-centered) but most of it.
|
Not everything OC has (as a few of them are really MC-centered) but most of it.
|
||||||
|
|
||||||
|
- `computer` component
|
||||||
- `data` component (note: deflate, sha256 and aes impl are callbacks, to keep NN small and simple)
|
- `data` component (note: deflate, sha256 and aes impl are callbacks, to keep NN small and simple)
|
||||||
- `modem` component
|
|
||||||
- `tunnel` component
|
- `tunnel` component
|
||||||
- `internet` component (note: NN does not handle internet requests, those are up to the emulator)
|
- `internet` component (note: NN does not handle internet requests, those are up to the emulator)
|
||||||
- `relay` component (note: OCDoc still refers to it as `access_point`)
|
- `relay` component (note: OCDoc still refers to it as `access_point`)
|
||||||
- `computer` component
|
|
||||||
- `geolyzer` component
|
- `geolyzer` component
|
||||||
- `net_splitter` component
|
- `net_splitter` component
|
||||||
- `redstone` component
|
- `redstone` component
|
||||||
@@ -48,11 +46,11 @@ Not everything OC has (as a few of them are really MC-centered) but most of it.
|
|||||||
- `serial` component, for serial communications with other devices (see Serial)
|
- `serial` component, for serial communications with other devices (see Serial)
|
||||||
- `iron_noteblock` component
|
- `iron_noteblock` component
|
||||||
- `colorful_lamp` component
|
- `colorful_lamp` component
|
||||||
- OpenSolidState flash storage
|
|
||||||
|
|
||||||
# To make it good
|
# To make it good (after API is stable)
|
||||||
|
|
||||||
- make more stuff const if it can be. Gotta help out the optimizer
|
- make more stuff const if it can be. Gotta help out the optimizer
|
||||||
|
- put a bunch of internal-only functions as fastcall
|
||||||
- write a bunch of unit tests to ensure the public API works correctly
|
- write a bunch of unit tests to ensure the public API works correctly
|
||||||
- ensure OOMs are recoverable
|
- ensure OOMs are recoverable
|
||||||
- do a hude audit for bugs at some point
|
- do a hude audit for bugs at some point
|
||||||
@@ -60,9 +58,11 @@ Not everything OC has (as a few of them are really MC-centered) but most of it.
|
|||||||
# To make it fast
|
# To make it fast
|
||||||
|
|
||||||
NOTE: we're mostly bottlenecked by the architecture (typically a Lua VM) and the intentional bottlenecking from call costs.
|
NOTE: we're mostly bottlenecked by the architecture (typically a Lua VM) and the intentional bottlenecking from call costs.
|
||||||
|
breaking changes are allowed but like try to avoid them.
|
||||||
|
|
||||||
- make signals use a circular buffer instead of a simple array
|
- make signals use a circular buffer instead of a simple array
|
||||||
- use more arenas if possible
|
- use more arenas if possible
|
||||||
|
- reduce pointer nesting, not only for simplicity, but so we spend less time reading from main memory
|
||||||
|
|
||||||
# Component extensions
|
# Component extensions
|
||||||
|
|
||||||
@@ -143,9 +143,9 @@ The `vt` component has:
|
|||||||
- `getColor(index: integer): integer`, to get a color
|
- `getColor(index: integer): integer`, to get a color
|
||||||
- `setColor(index: integer, color: integer): integer`, sets a color and returns the old one. Characters who's colors were table indexes would be updated
|
- `setColor(index: integer, color: integer): integer`, sets a color and returns the old one. Characters who's colors were table indexes would be updated
|
||||||
- `setForeground(color: integer, fromTable?: boolean)`, sets a foreground color, optionally as a table index
|
- `setForeground(color: integer, fromTable?: boolean)`, sets a foreground color, optionally as a table index
|
||||||
- `getForeground(): integer, integer?`, returns what the foreground color was, and the palette index if applicable
|
- `getForeground(): integer, integer?`, returns what the foreground color was, and the table index if applicable
|
||||||
- `setBackground(color: integer, fromTable?: boolean)`, sets a background color, optionally as a table index
|
- `setBackground(color: integer, fromTable?: boolean)`, sets a background color, optionally as a table index
|
||||||
- `getBackground(): integer, integer?`, returns what the background color was, and the palette index if applicable
|
- `getBackground(): integer, integer?`, returns what the background color was, and the table index if applicable
|
||||||
- `set(idx: integer, data: string): boolean`, to write to the screen's unicode buffer. While `data` is UTF-8, the buffer stores codepoints. Pretend
|
- `set(idx: integer, data: string): boolean`, to write to the screen's unicode buffer. While `data` is UTF-8, the buffer stores codepoints. Pretend
|
||||||
the terminal does an internal conversion from UTF-8 to UTF-32
|
the terminal does an internal conversion from UTF-8 to UTF-32
|
||||||
- `getColorOf(idx: integer): integer, integer, integer?, integer?`, to get the foreground color, background color, and palette indexes of a tile
|
- `getColorOf(idx: integer): integer, integer, integer?, integer?`, to get the foreground color, background color, and palette indexes of a tile
|
||||||
@@ -160,10 +160,11 @@ If `x` and `y` are 0-indexed, then `x + y * width` is the index in the buffer
|
|||||||
|
|
||||||
The `cd_drive` component has:
|
The `cd_drive` component has:
|
||||||
- `hasDisk(): boolean`, to check whether a disk is in the drive
|
- `hasDisk(): boolean`, to check whether a disk is in the drive
|
||||||
- `isReadonly(): boolean`, to check where the drive is read-only (often is)
|
- `isReadonly(): boolean`, to check whether the drive is read-only (often is)
|
||||||
- `isDiskErasable(): boolean`, to check whether the disk is erasable, which requires support from both the disk and the drive
|
- `isDiskErasable(): boolean`, to check whether the disk is erasable, which requires support from both the disk and the drive
|
||||||
|
- `getCapacity(): integer`, gets the capacity of the disk
|
||||||
- `tell(): integer`, current 0-indexed byte offset into the disk
|
- `tell(): integer`, current 0-indexed byte offset into the disk
|
||||||
- `seekTo(position: integer): boolean`, seek to a current 0-indexed byte offset in the disk
|
- `seekTo(position: integer): boolean`, seek to a 0-indexed byte offset in the disk
|
||||||
- `moveBy(delta: integer): boolean`, move the current position by some amount of bytes (+/-), can wrap around
|
- `moveBy(delta: integer): boolean`, move the current position by some amount of bytes (+/-), can wrap around
|
||||||
- `maxReadSize(): integer`, to return the maximum size of a read
|
- `maxReadSize(): integer`, to return the maximum size of a read
|
||||||
- `read(len: integer): string`, to read some data. Does wrap around
|
- `read(len: integer): string`, to read some data. Does wrap around
|
||||||
@@ -186,7 +187,9 @@ Tape has high capacity, CDs do not.
|
|||||||
|
|
||||||
### CDs vs unmanaged floppies
|
### CDs vs unmanaged floppies
|
||||||
|
|
||||||
CDs are slower for random reads as they have no cache.
|
CDs require special software support, while floppies appear as just smaller HDDs.
|
||||||
|
Unmanaged floppies are always erasable, while CDs may not be.
|
||||||
|
CDs are typically lower capacity.
|
||||||
|
|
||||||
## LED
|
## LED
|
||||||
|
|
||||||
|
|||||||
30
src/main.c
30
src/main.c
@@ -133,6 +133,36 @@ static nn_Exit ne_modemBullshit(nn_ModemRequest *req) {
|
|||||||
if(req->action == NN_MODEM_DROP) {
|
if(req->action == NN_MODEM_DROP) {
|
||||||
return NN_OK;
|
return NN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(req->action == NN_MODEM_ISOPEN) {
|
||||||
|
int port = req->isOpen.port;
|
||||||
|
req->isOpen.opened = port >= 1 && port <= 3;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(req->action == NN_MODEM_OPEN) {
|
||||||
|
printf("pretend we opened port %zu\n", req->openPort);
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(req->action == NN_MODEM_CLOSE) {
|
||||||
|
printf("pretend we closed ");
|
||||||
|
if(req->closePort == NN_CLOSEPORTS) {
|
||||||
|
printf("all ports\n");
|
||||||
|
} else {
|
||||||
|
printf("port %zu\n", req->closePort);
|
||||||
|
}
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(req->action == NN_MODEM_GETPORTS) {
|
||||||
|
// lies
|
||||||
|
req->getPorts.len = 3;
|
||||||
|
req->getPorts.activePorts[0] = 1;
|
||||||
|
req->getPorts.activePorts[1] = 2;
|
||||||
|
req->getPorts.activePorts[2] = 3;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if(req->action == NN_MODEM_SEND) {
|
if(req->action == NN_MODEM_SEND) {
|
||||||
req->send.strengthSent = req->modem->maxRange;
|
req->send.strengthSent = req->modem->maxRange;
|
||||||
printf("Transmission from %s to %s (port %zu) of %zu bytes (%zu values)\n", req->localAddress, req->send.address == NULL ? "*" : req->send.address, req->send.port, req->send.contents->buflen, req->send.contents->valueCount);
|
printf("Transmission from %s to %s (port %zu) of %zu bytes (%zu values)\n", req->localAddress, req->send.address == NULL ? "*" : req->send.address, req->send.port, req->send.contents->buflen, req->send.contents->valueCount);
|
||||||
|
|||||||
155
src/neonucleus.c
155
src/neonucleus.c
@@ -153,6 +153,7 @@ void nn_ardestroy(nn_Arena *arena) {
|
|||||||
nn_free(&arena->ctx, cur->memory, cur->cap);
|
nn_free(&arena->ctx, cur->memory, cur->cap);
|
||||||
nn_free(&arena->ctx, cur, sizeof(*cur));
|
nn_free(&arena->ctx, cur, sizeof(*cur));
|
||||||
}
|
}
|
||||||
|
arena->block = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nn_ArenaBlock *nn_arallocblock(nn_Context *ctx, size_t cap) {
|
nn_ArenaBlock *nn_arallocblock(nn_Context *ctx, size_t cap) {
|
||||||
@@ -4124,67 +4125,12 @@ nn_Exit nn_pushModemMessage(nn_Computer *C, const char *modemAddress, const char
|
|||||||
return nn_pushSignal(C, signalVals);
|
return nn_pushSignal(C, signalVals);
|
||||||
}
|
}
|
||||||
|
|
||||||
nn_Computer *nn_fromWrappedComputer(nn_Component *component) {
|
|
||||||
if(nn_strcmp(component->internalID, "NN_WRAPPEDCOMPUTER") == 0) {
|
|
||||||
return component->state;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to) {
|
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to) {
|
||||||
const char *err = nn_getError(from);
|
const char *err = nn_getError(from);
|
||||||
if(err != NULL) nn_setError(to, err);
|
if(err != NULL) nn_setError(to, err);
|
||||||
return exit;
|
return exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum nn_CompNum {
|
|
||||||
NN_COMPNUM_START,
|
|
||||||
NN_COMPNUM_STOP,
|
|
||||||
NN_COMPNUM_ISRUNNING,
|
|
||||||
NN_COMPNUM_GETDEVICEINFO,
|
|
||||||
NN_COMPNUM_CRASH,
|
|
||||||
NN_COMPNUM_GETARCH,
|
|
||||||
NN_COMPNUM_ISROBOT,
|
|
||||||
NN_COMPNUM_BEEP,
|
|
||||||
|
|
||||||
NN_COMPNUM_COUNT,
|
|
||||||
} nn_CompNum;
|
|
||||||
|
|
||||||
static nn_Exit nn_computerHandler(nn_ComponentRequest *req) {
|
|
||||||
if(req->action == NN_COMP_DROP) return NN_OK;
|
|
||||||
if(req->action == NN_COMP_USERDATA) return NN_OK;
|
|
||||||
nn_Computer *src = req->computer;
|
|
||||||
if(src) nn_setError(src, "computer: not implemented yet");
|
|
||||||
return NN_EBADCALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nn_Component *nn_wrapComputer(nn_Computer *computer) {
|
|
||||||
const nn_Method methods[NN_COMPNUM_COUNT] = {
|
|
||||||
[NN_COMPNUM_START] = {"start", "function(): boolean - Attempts to turn on the computer, will return false if it is already on or it failed", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_STOP] = {"stop", "function(): boolean - Attempts to turn ooff the computer, will return false if it is already off or it failed", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_ISRUNNING] = {"isRunning", "function(): boolean - Returns whether it is running or not", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_GETDEVICEINFO] = {"getDeviceInfo", "function(): table<string, table<string, string>> - Returns a table of device information for the computer", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_CRASH] = {"crash", "function(error: string) - Will forcefully crash the computer, if it is running", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_GETARCH] = {"getArchitecture", "function(): string - Get the architecture of the computer", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_ISROBOT] = {"isRobot", "function(): boolean - Returns whether the computer is a robot", NN_INDIRECT},
|
|
||||||
[NN_COMPNUM_BEEP] = {"beep", "function(frequency?: number, duration?: number, volume?: number) - Makes the computer make a beep sound", NN_INDIRECT},
|
|
||||||
};
|
|
||||||
|
|
||||||
nn_Component *c = nn_createComponent(computer->universe, computer->address, "computer");
|
|
||||||
if(c == NULL) return NULL;
|
|
||||||
nn_setComponentState(c, computer);
|
|
||||||
nn_setComponentHandler(c, nn_computerHandler);
|
|
||||||
if(nn_setComponentTypeID(c, "NN_WRAPPEDCOMPUTER")) {
|
|
||||||
nn_dropComponent(c);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(nn_setComponentMethodsArray(c, methods, NN_COMPNUM_COUNT)) {
|
|
||||||
nn_dropComponent(c);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum nn_EENum {
|
typedef enum nn_EENum {
|
||||||
NN_EENUM_GETSIZE,
|
NN_EENUM_GETSIZE,
|
||||||
NN_EENUM_GETDATASIZE,
|
NN_EENUM_GETDATASIZE,
|
||||||
@@ -4827,7 +4773,7 @@ bool nn_mergeFilesystems(nn_Filesystem *merged, const nn_Filesystem *fs, size_t
|
|||||||
for(size_t i = 1; i < len; i++) {
|
for(size_t i = 1; i < len; i++) {
|
||||||
merged->readsPerTick += fs[i].readsPerTick;
|
merged->readsPerTick += fs[i].readsPerTick;
|
||||||
merged->writesPerTick += fs[i].writesPerTick;
|
merged->writesPerTick += fs[i].writesPerTick;
|
||||||
if(merged->maxReadSize < fs[i].maxReadSize) merged->maxReadSize = fs[i].maxReadSize;
|
if(merged->maxReadSize > fs[i].maxReadSize) merged->maxReadSize = fs[i].maxReadSize;
|
||||||
merged->dataEnergyCost += fs[i].dataEnergyCost;
|
merged->dataEnergyCost += fs[i].dataEnergyCost;
|
||||||
merged->spaceTotal += fs[i].spaceTotal;
|
merged->spaceTotal += fs[i].spaceTotal;
|
||||||
}
|
}
|
||||||
@@ -6740,6 +6686,7 @@ typedef enum nn_ModemNum {
|
|||||||
NN_MODEMNUM_ISWIRELESS,
|
NN_MODEMNUM_ISWIRELESS,
|
||||||
NN_MODEMNUM_MAXPACKETSIZE,
|
NN_MODEMNUM_MAXPACKETSIZE,
|
||||||
NN_MODEMNUM_MAXVALUES,
|
NN_MODEMNUM_MAXVALUES,
|
||||||
|
NN_MODEMNUM_MAXPORTS,
|
||||||
|
|
||||||
NN_MODEMNUM_GETSTRENGTH,
|
NN_MODEMNUM_GETSTRENGTH,
|
||||||
NN_MODEMNUM_SETSTRENGTH,
|
NN_MODEMNUM_SETSTRENGTH,
|
||||||
@@ -6814,6 +6761,15 @@ static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
|||||||
req->returnCount = 1;
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, state->modem.maxValues);
|
return nn_pushinteger(C, state->modem.maxValues);
|
||||||
}
|
}
|
||||||
|
if(method == NN_MODEMNUM_MAXPORTS) {
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushinteger(C, state->modem.maxOpenPorts);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_MAXSTRENGTH) {
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushinteger(C, state->modem.maxRange);
|
||||||
|
}
|
||||||
|
|
||||||
if(method == NN_MODEMNUM_GETSTRENGTH) {
|
if(method == NN_MODEMNUM_GETSTRENGTH) {
|
||||||
mreq.action = NN_MODEM_GETSTRENGTH;
|
mreq.action = NN_MODEM_GETSTRENGTH;
|
||||||
e = state->handler(&mreq);
|
e = state->handler(&mreq);
|
||||||
@@ -6821,9 +6777,89 @@ static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
|||||||
req->returnCount = 1;
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, mreq.strength);
|
return nn_pushinteger(C, mreq.strength);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_MAXSTRENGTH) {
|
if(method == NN_MODEMNUM_SETSTRENGTH) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t strength = nn_tointeger(C, 0);
|
||||||
|
if(strength < 0) strength = 0;
|
||||||
|
if(strength > state->modem.maxRange) strength = state->modem.maxRange;
|
||||||
|
mreq.action = NN_MODEM_SETSTRENGTH;
|
||||||
|
mreq.strength = strength;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) return e;
|
||||||
req->returnCount = 1;
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, state->modem.maxRange);
|
// allow controller to change it
|
||||||
|
return nn_pushinteger(C, mreq.strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(method == NN_MODEMNUM_ISOPEN) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t port = nn_tointeger(C, 0);
|
||||||
|
if(port < 1 || port > NN_MAX_PORT) {
|
||||||
|
nn_setError(C, "invalid port index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
mreq.action = NN_MODEM_ISOPEN;
|
||||||
|
mreq.isOpen.port = port;
|
||||||
|
mreq.isOpen.opened = false;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushbool(C, mreq.isOpen.opened);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_OPEN) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t port = nn_tointeger(C, 0);
|
||||||
|
if(port < 1 || port > NN_MAX_PORT) {
|
||||||
|
nn_setError(C, "invalid port index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
mreq.action = NN_MODEM_OPEN;
|
||||||
|
mreq.openPort = port;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_CLOSE) {
|
||||||
|
e = nn_defaultinteger(C, 0, NN_CLOSEPORTS);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t port = nn_tointeger(C, 0);
|
||||||
|
if((port < 1 || port > NN_MAX_PORT) && port != NN_CLOSEPORTS) {
|
||||||
|
nn_setError(C, "invalid port index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
mreq.action = NN_MODEM_CLOSE;
|
||||||
|
mreq.closePort = port;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_GETPORTS) {
|
||||||
|
e = nn_defaultinteger(C, 0, NN_CLOSEPORTS);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t port = nn_tointeger(C, 0);
|
||||||
|
if((port < 1 || port > NN_MAX_PORT) && port != NN_CLOSEPORTS) {
|
||||||
|
nn_setError(C, "invalid port index");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
mreq.action = NN_MODEM_GETPORTS;
|
||||||
|
size_t cap = state->modem.maxOpenPorts;
|
||||||
|
unsigned short *ports = nn_alloc(ctx, sizeof(unsigned short) * cap);
|
||||||
|
if(ports == NULL) return NN_ENOMEM;
|
||||||
|
mreq.getPorts.activePorts = ports;
|
||||||
|
mreq.getPorts.len = cap;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) goto fail;
|
||||||
|
req->returnCount = 1;
|
||||||
|
for(size_t i = 0; i < mreq.getPorts.len; i++) {
|
||||||
|
e = nn_pushinteger(C, mreq.getPorts.activePorts[i]);
|
||||||
|
if(e) goto fail;
|
||||||
|
}
|
||||||
|
return nn_pusharraytable(C, mreq.getPorts.len);
|
||||||
|
fail:
|
||||||
|
nn_free(ctx, ports, sizeof(unsigned short) * cap);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(method == NN_MODEMNUM_BROADCAST) {
|
if(method == NN_MODEMNUM_BROADCAST) {
|
||||||
@@ -6907,6 +6943,7 @@ nn_Component *nn_createModem(nn_Universe *universe, const char *address, const n
|
|||||||
[NN_MODEMNUM_ISWIRELESS] = {"isWireless", "function(): boolean - Returns whether the modem supports wireless connectivity", NN_DIRECT},
|
[NN_MODEMNUM_ISWIRELESS] = {"isWireless", "function(): boolean - Returns whether the modem supports wireless connectivity", NN_DIRECT},
|
||||||
[NN_MODEMNUM_MAXPACKETSIZE] = {"maxPacketSize", "function(): integer - Returns the maximum logical packet size", NN_DIRECT},
|
[NN_MODEMNUM_MAXPACKETSIZE] = {"maxPacketSize", "function(): integer - Returns the maximum logical packet size", NN_DIRECT},
|
||||||
[NN_MODEMNUM_MAXVALUES] = {"maxValues", "function(): integer - Returns the maximum amount of values", NN_DIRECT},
|
[NN_MODEMNUM_MAXVALUES] = {"maxValues", "function(): integer - Returns the maximum amount of values", NN_DIRECT},
|
||||||
|
[NN_MODEMNUM_MAXPORTS] = {"maxOpenPorts", "function(): integer - Returns the maximum amount of ports that can be simultaneously open", NN_DIRECT},
|
||||||
|
|
||||||
[NN_MODEMNUM_GETSTRENGTH] = {"getStrength", "function(): integer - Returns the range of wireless message", NN_DIRECT},
|
[NN_MODEMNUM_GETSTRENGTH] = {"getStrength", "function(): integer - Returns the range of wireless message", NN_DIRECT},
|
||||||
[NN_MODEMNUM_SETSTRENGTH] = {"setStrength", "function(strength: integer): integer - Changes the wireless signal strength", NN_INDIRECT},
|
[NN_MODEMNUM_SETSTRENGTH] = {"setStrength", "function(strength: integer): integer - Changes the wireless signal strength", NN_INDIRECT},
|
||||||
@@ -6959,7 +6996,7 @@ nn_Modem nn_defaultWirelessModems[2] = {
|
|||||||
.maxRange = 16,
|
.maxRange = 16,
|
||||||
.maxValues = 8,
|
.maxValues = 8,
|
||||||
.maxPacketSize = 8192,
|
.maxPacketSize = 8192,
|
||||||
.maxOpenPorts = 16,
|
.maxOpenPorts = 1,
|
||||||
.isWired = true,
|
.isWired = true,
|
||||||
.basePacketCost = 0.1,
|
.basePacketCost = 0.1,
|
||||||
.fullPacketCost = 0.5,
|
.fullPacketCost = 0.5,
|
||||||
|
|||||||
@@ -1040,16 +1040,7 @@ nn_Exit nn_pushSignal(nn_Computer *computer, size_t valueCount);
|
|||||||
// If there is no signal, it returns EBADSTATE
|
// If there is no signal, it returns EBADSTATE
|
||||||
nn_Exit nn_popSignal(nn_Computer *computer, size_t *valueCount);
|
nn_Exit nn_popSignal(nn_Computer *computer, size_t *valueCount);
|
||||||
|
|
||||||
// The high-level API of the built-in component classes.
|
|
||||||
// These components still make no assumptions about the OS, and still require handlers to connect them to the outside work.
|
|
||||||
|
|
||||||
// Wrapping a computer as a component.
|
|
||||||
// It's a new instance each time.
|
|
||||||
// The computer MUST NOT be dropped before this component is fully gone.
|
|
||||||
|
|
||||||
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to);
|
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to);
|
||||||
nn_Computer *nn_fromWrappedComputer(nn_Component *component);
|
|
||||||
nn_Component *nn_wrapComputer(nn_Computer *computer);
|
|
||||||
|
|
||||||
// EEPROM class
|
// EEPROM class
|
||||||
|
|
||||||
@@ -1949,7 +1940,7 @@ typedef struct nn_ModemRequest {
|
|||||||
size_t closePort;
|
size_t closePort;
|
||||||
struct {
|
struct {
|
||||||
// store the port numbers in this buffer
|
// store the port numbers in this buffer
|
||||||
size_t *activePorts;
|
unsigned short *activePorts;
|
||||||
// the amount of active ports.
|
// the amount of active ports.
|
||||||
// the initial value is the capacity of activePorts
|
// the initial value is the capacity of activePorts
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|||||||
Reference in New Issue
Block a user