mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 17:13:31 +02:00
Compare commits
9 Commits
6499f919d0
...
087fd1e9b3
Author | SHA1 | Date | |
---|---|---|---|
|
087fd1e9b3 | ||
|
82f62f5158 | ||
|
b6d1131353 | ||
|
bf473f5c4c | ||
|
255df4d352 | ||
|
48faf57d84 | ||
|
3f3e18dbe8 | ||
|
cd02f31368 | ||
|
b7ddf9c34e |
4
TODO.md
4
TODO.md
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
- `hologram` component
|
- `hologram` component
|
||||||
- `computer` component
|
- `computer` component
|
||||||
- `tunnel` component
|
|
||||||
- `data` component (with error correction codes and maybe synthesizing audio)
|
- `data` component (with error correction codes and maybe synthesizing audio)
|
||||||
- `redstone` component
|
- `redstone` component
|
||||||
- `internet` component
|
- `internet` component
|
||||||
@ -44,4 +43,7 @@
|
|||||||
- rework some interfaces to use pre-allocated or stack-allocated memory more
|
- rework some interfaces to use pre-allocated or stack-allocated memory more
|
||||||
- use dynamic arrays for signals (and maybe components), but still keep the maximums to prevent memory hogging
|
- use dynamic arrays for signals (and maybe components), but still keep the maximums to prevent memory hogging
|
||||||
- setup an extensive testing system to find bugs easier
|
- setup an extensive testing system to find bugs easier
|
||||||
|
- optimize the codebase by using globals instead of universe userdata
|
||||||
- use compiler hints to let the optimizer make the code even faster
|
- use compiler hints to let the optimizer make the code even faster
|
||||||
|
- (maybe) rework a bunch of internal structures to use tagged unions over vtables (such as components). This may make certain APIs unnecessary or slightly
|
||||||
|
different. This can improve performance at the cost of making the codebase more complex
|
||||||
|
@ -52,6 +52,7 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
|
|||||||
if(strict) "-Werror" else "",
|
if(strict) "-Werror" else "",
|
||||||
"-std=gnu23",
|
"-std=gnu23",
|
||||||
"-Wno-keyword-macro", // cuz bools
|
"-Wno-keyword-macro", // cuz bools
|
||||||
|
"-fPIE",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,6 +62,9 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
|
|||||||
.files = &.{
|
.files = &.{
|
||||||
"src/tinycthread.c",
|
"src/tinycthread.c",
|
||||||
},
|
},
|
||||||
|
.flags = &.{
|
||||||
|
"-fPIE",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +152,15 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const engineStatic = b.addStaticLibrary(.{
|
const engineStatic = b.addStaticLibrary(.{
|
||||||
.name = "neonucleus",
|
.name = "neonucleus",
|
||||||
.root_module = engineMod,
|
.root_module = engineMod,
|
||||||
|
.pic = true,
|
||||||
|
.code_model = .default,
|
||||||
});
|
});
|
||||||
|
|
||||||
const engineShared = b.addSharedLibrary(.{
|
const engineShared = b.addSharedLibrary(.{
|
||||||
.name = if(os == .windows) "neonucleusdll" else "neonucleus",
|
.name = if(os == .windows) "neonucleusdll" else "neonucleus",
|
||||||
.root_module = engineMod,
|
.root_module = engineMod,
|
||||||
|
.pic = true,
|
||||||
|
.code_model = .default,
|
||||||
});
|
});
|
||||||
|
|
||||||
const engineStep = b.step("engine", "Builds the engine as a static library");
|
const engineStep = b.step("engine", "Builds the engine as a static library");
|
||||||
|
@ -1,7 +1,59 @@
|
|||||||
#include "../neonucleus.h"
|
#include "../neonucleus.h"
|
||||||
|
|
||||||
|
typedef struct nn_loopTunnel_t {
|
||||||
|
nn_Context ctx;
|
||||||
|
nn_debugLoopbackNetworkOpts opts;
|
||||||
|
char wakeup[NN_MAX_WAKEUPMSG];
|
||||||
|
nn_size_t wakeupLen;
|
||||||
|
} nn_loopTunnel_t;
|
||||||
|
|
||||||
|
static void nni_debugTunnel_deinit(nn_loopTunnel_t *t) {
|
||||||
|
nn_Alloc a = t->ctx.allocator;
|
||||||
|
nn_deallocStr(&a, t->opts.address);
|
||||||
|
nn_dealloc(&a, t, sizeof(nn_loopTunnel_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static nn_size_t nni_debugTunnel_getChannel(nn_loopTunnel_t *t, char *buf, nn_errorbuf_t err) {
|
||||||
|
nn_strcpy(buf, "loopback");
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nn_size_t nni_debugTunnel_getWakeMessage(nn_loopTunnel_t *t, char *buf, nn_errorbuf_t err) {
|
||||||
|
nn_memcpy(buf, t->wakeup, t->wakeupLen);
|
||||||
|
return t->wakeupLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nn_size_t nni_debugTunnel_setWakeMessage(nn_loopTunnel_t *t, const char *buf, nn_size_t buflen, nn_bool_t fuzzy, nn_errorbuf_t err) {
|
||||||
|
if(buflen > NN_MAX_CHANNEL_SIZE) buflen = NN_MAX_CHANNEL_SIZE;
|
||||||
|
nn_memcpy(t->wakeup, buf, buflen);
|
||||||
|
t->wakeupLen = buflen;
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_debugTunnel_send(nn_loopTunnel_t *t, nn_value *values, nn_size_t valueCount, nn_errorbuf_t err) {
|
||||||
|
nn_pushNetworkMessage(t->opts.computer, t->opts.address, "loopback", NN_TUNNEL_PORT, 0, values, valueCount);
|
||||||
|
}
|
||||||
|
|
||||||
nn_tunnel *nn_debugLoopbackTunnel(nn_Context *context, nn_debugLoopbackNetworkOpts opts, nn_networkControl control) {
|
nn_tunnel *nn_debugLoopbackTunnel(nn_Context *context, nn_debugLoopbackNetworkOpts opts, nn_networkControl control) {
|
||||||
nn_tunnelTable table = {};
|
nn_Alloc *alloc = &context->allocator;
|
||||||
|
|
||||||
|
nn_loopTunnel_t *t = nn_alloc(alloc, sizeof(nn_loopTunnel_t));
|
||||||
|
t->ctx = *context;
|
||||||
|
t->opts = opts;
|
||||||
|
t->opts.address = nn_strdup(alloc, t->opts.address);
|
||||||
|
t->wakeupLen = 0;
|
||||||
|
|
||||||
|
nn_tunnelTable table = {
|
||||||
|
.userdata = t,
|
||||||
|
.deinit = (void *)nni_debugTunnel_deinit,
|
||||||
|
|
||||||
|
.maxValues = opts.maxValues,
|
||||||
|
.maxPacketSize = opts.maxPacketSize,
|
||||||
|
.getChannel = (void *)nni_debugTunnel_getChannel,
|
||||||
|
.getWakeMessage = (void *)nni_debugTunnel_getWakeMessage,
|
||||||
|
.setWakeMessage = (void *)nni_debugTunnel_setWakeMessage,
|
||||||
|
.send = (void *)nni_debugTunnel_send,
|
||||||
|
};
|
||||||
|
|
||||||
return nn_newTunnel(context, table, control);
|
return nn_newTunnel(context, table, control);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,114 @@ void nn_tunnel_destroy(void *_, nn_component *component, nn_tunnel *tunnel) {
|
|||||||
nn_destroyTunnel(tunnel);
|
nn_destroyTunnel(tunnel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_maxPacketSize(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_return_integer(computer, tunnel->table.maxPacketSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_maxValues(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_return_integer(computer, tunnel->table.maxValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_getChannel(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
char buf[NN_MAX_CHANNEL_SIZE];
|
||||||
|
nn_lock(&tunnel->ctx, tunnel->lock);
|
||||||
|
nn_size_t len = tunnel->table.getChannel(tunnel->table.userdata, buf, err);
|
||||||
|
nn_unlock(&tunnel->ctx, tunnel->lock);
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nn_return_string(computer, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_getWakeMessage(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
char buf[NN_MAX_CHANNEL_SIZE];
|
||||||
|
nn_lock(&tunnel->ctx, tunnel->lock);
|
||||||
|
nn_size_t len = tunnel->table.getWakeMessage(tunnel->table.userdata, buf, err);
|
||||||
|
nn_unlock(&tunnel->ctx, tunnel->lock);
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nn_return_string(computer, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_setWakeMessage(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_size_t buflen;
|
||||||
|
const char *buf = nn_toString(nn_getArgument(computer, 0), &buflen);
|
||||||
|
|
||||||
|
if(buf == NULL) {
|
||||||
|
nn_setCError(computer, "invalid wake message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buflen > NN_MAX_WAKEUPMSG) {
|
||||||
|
buflen = NN_MAX_WAKEUPMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_bool_t fuzzy = nn_toBoolean(nn_getArgument(computer, 1)); // nil is false
|
||||||
|
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
|
||||||
|
nn_lock(&tunnel->ctx, tunnel->lock);
|
||||||
|
buflen = tunnel->table.setWakeMessage(tunnel->table.userdata, buf, buflen, fuzzy, err);
|
||||||
|
nn_unlock(&tunnel->ctx, tunnel->lock);
|
||||||
|
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_return_string(computer, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nni_tunnel_send(nn_tunnel *tunnel, void *_, nn_component *component, nn_computer *computer) {
|
||||||
|
nn_value vals[tunnel->table.maxValues];
|
||||||
|
nn_size_t valLen = nn_getArgumentCount(computer);
|
||||||
|
|
||||||
|
if(valLen > tunnel->table.maxValues) {
|
||||||
|
nn_setCError(computer, "too many values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(nn_size_t i = 0; i < valLen; i++) {
|
||||||
|
vals[i] = nn_getArgument(computer, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_size_t bytesSent = nn_measurePacketSize(vals, valLen);
|
||||||
|
if(bytesSent > tunnel->table.maxPacketSize) {
|
||||||
|
nn_setCError(computer, "packet too big");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nn_simulateBufferedIndirect(component, bytesSent, tunnel->ctrl.packetBytesPerTick);
|
||||||
|
double d = (double)bytesSent / tunnel->table.maxPacketSize;
|
||||||
|
nn_addHeat(computer, d * tunnel->ctrl.heatPerFullPacket);
|
||||||
|
nn_removeEnergy(computer, d * tunnel->ctrl.energyPerFullPacket);
|
||||||
|
|
||||||
|
nn_errorbuf_t err = "";
|
||||||
|
nn_lock(&tunnel->ctx, tunnel->lock);
|
||||||
|
tunnel->table.send(tunnel->table.userdata, vals, valLen, err);
|
||||||
|
nn_unlock(&tunnel->ctx, tunnel->lock);
|
||||||
|
if(!nn_error_isEmpty(err)) {
|
||||||
|
nn_setError(computer, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_return_boolean(computer, true);
|
||||||
|
}
|
||||||
|
|
||||||
void nn_loadTunnelTable(nn_universe *universe) {
|
void nn_loadTunnelTable(nn_universe *universe) {
|
||||||
nn_componentTable *tunnelTable = nn_newComponentTable(nn_getAllocator(universe), "tunnel", NULL, NULL, (nn_componentDestructor *)nn_tunnel_destroy);
|
nn_componentTable *tunnelTable = nn_newComponentTable(nn_getAllocator(universe), "tunnel", NULL, NULL, (nn_componentDestructor *)nn_tunnel_destroy);
|
||||||
nn_storeUserdata(universe, "NN:TUNNEL", tunnelTable);
|
nn_storeUserdata(universe, "NN:TUNNEL", tunnelTable);
|
||||||
|
|
||||||
|
nn_defineMethod(tunnelTable, "maxPacketSize", (nn_componentMethod *)nni_tunnel_maxPacketSize, "maxPacketSize(): integer - Returns the maximum size of a packet");
|
||||||
|
nn_defineMethod(tunnelTable, "maxValues", (nn_componentMethod *)nni_tunnel_maxValues, "maxValues(): integer - the maximum number of values which can be sent in a packet");
|
||||||
|
nn_defineMethod(tunnelTable, "getChannel", (nn_componentMethod *)nni_tunnel_getChannel, "getChannel(): string - Gets the ID of the communications channel of the tunnel. Under normal conditions, there are only 2 cards in the same universe which share this.");
|
||||||
|
nn_defineMethod(tunnelTable, "getWakeMessage", (nn_componentMethod *)nni_tunnel_getWakeMessage, "getWakeMessage(): string - Returns the current wake message");
|
||||||
|
nn_defineMethod(tunnelTable, "setWakeMessage", (nn_componentMethod *)nni_tunnel_setWakeMessage, "setWakeMessage(msg: string[, fuzzy: boolean]): string - Sets the new wake message");
|
||||||
|
nn_defineMethod(tunnelTable, "send", (nn_componentMethod *)nni_tunnel_send, "send(...): boolean - Sends a tunnel message. Returns whether it was sent.");
|
||||||
}
|
}
|
||||||
|
|
||||||
nn_component *nn_addTunnel(nn_computer *computer, nn_address address, int slot, nn_tunnel *tunnel) {
|
nn_component *nn_addTunnel(nn_computer *computer, nn_address address, int slot, nn_tunnel *tunnel) {
|
||||||
|
@ -20,43 +20,43 @@ static void nni_veeprom_deinit(nn_veeprom *veeprom) {
|
|||||||
nn_dealloc(&a, veeprom, sizeof(nn_veeprom));
|
nn_dealloc(&a, veeprom, sizeof(nn_veeprom));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nni_veeprom_getLabel(nn_veeprom *veeprom, char *buf, nn_size_t *buflen) {
|
static void nni_veeprom_getLabel(nn_veeprom *veeprom, char *buf, nn_size_t *buflen, nn_errorbuf_t err) {
|
||||||
nn_memcpy(buf, veeprom->label, veeprom->labelLen);
|
nn_memcpy(buf, veeprom->label, veeprom->labelLen);
|
||||||
*buflen = veeprom->labelLen;
|
*buflen = veeprom->labelLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nn_size_t nni_veeprom_setLabel(nn_veeprom *veeprom, const char *buf, nn_size_t buflen) {
|
static nn_size_t nni_veeprom_setLabel(nn_veeprom *veeprom, const char *buf, nn_size_t buflen, nn_errorbuf_t err) {
|
||||||
if(buflen > NN_LABEL_SIZE) buflen = NN_LABEL_SIZE;
|
if(buflen > NN_LABEL_SIZE) buflen = NN_LABEL_SIZE;
|
||||||
nn_memcpy(veeprom->label, buf, buflen);
|
nn_memcpy(veeprom->label, buf, buflen);
|
||||||
veeprom->labelLen = buflen;
|
veeprom->labelLen = buflen;
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nn_size_t nni_veeprom_get(nn_veeprom *veeprom, char *buf) {
|
static nn_size_t nni_veeprom_get(nn_veeprom *veeprom, char *buf, nn_errorbuf_t err) {
|
||||||
nn_memcpy(buf, veeprom->code, veeprom->codeLen);
|
nn_memcpy(buf, veeprom->code, veeprom->codeLen);
|
||||||
return veeprom->codeLen;
|
return veeprom->codeLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nni_veeprom_set(nn_veeprom *veeprom, const char *buf, nn_size_t len) {
|
static void nni_veeprom_set(nn_veeprom *veeprom, const char *buf, nn_size_t len, nn_errorbuf_t err) {
|
||||||
nn_memcpy(veeprom->code, buf, len);
|
nn_memcpy(veeprom->code, buf, len);
|
||||||
veeprom->codeLen = len;
|
veeprom->codeLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nn_size_t nni_veeprom_getData(nn_veeprom *veeprom, char *buf) {
|
static nn_size_t nni_veeprom_getData(nn_veeprom *veeprom, char *buf, nn_errorbuf_t err) {
|
||||||
nn_memcpy(buf, veeprom->data, veeprom->dataLen);
|
nn_memcpy(buf, veeprom->data, veeprom->dataLen);
|
||||||
return veeprom->dataLen;
|
return veeprom->dataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nni_veeprom_setData(nn_veeprom *veeprom, const char *buf, nn_size_t len) {
|
static void nni_veeprom_setData(nn_veeprom *veeprom, const char *buf, nn_size_t len, nn_errorbuf_t err) {
|
||||||
nn_memcpy(veeprom->data, buf, len);
|
nn_memcpy(veeprom->data, buf, len);
|
||||||
veeprom->dataLen = len;
|
veeprom->dataLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nn_bool_t nni_veeprom_isReadonly(nn_veeprom *eeprom) {
|
static nn_bool_t nni_veeprom_isReadonly(nn_veeprom *eeprom, nn_errorbuf_t err) {
|
||||||
return eeprom->isReadOnly;
|
return eeprom->isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nni_veeprom_makeReadonly(nn_veeprom *eeprom) {
|
static void nni_veeprom_makeReadonly(nn_veeprom *eeprom, nn_errorbuf_t err) {
|
||||||
eeprom->isReadOnly = true;
|
eeprom->isReadOnly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,20 +473,20 @@ nn_size_t nn_getReturnCount(nn_computer *computer) {
|
|||||||
return computer->retc;
|
return computer->retc;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *nn_serializeProgram(nn_computer *computer, nn_size_t *len) {
|
char *nn_serializeProgram(nn_computer *computer, nn_Alloc *alloc, nn_size_t *len) {
|
||||||
return computer->arch->serialize(computer, computer->archState, computer->arch->userdata, len);
|
return computer->arch->serialize(computer, alloc, computer->archState, computer->arch->userdata, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nn_deserializeProgram(nn_computer *computer, const char *memory, nn_size_t len) {
|
void nn_deserializeProgram(nn_computer *computer, const char *memory, nn_size_t len) {
|
||||||
computer->arch->deserialize(computer, memory, len, computer->archState, computer->arch->userdata);
|
computer->arch->deserialize(computer, memory, len, computer->archState, computer->arch->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nn_lockComputer(nn_computer *computer) {
|
nn_Context *nn_getComputerContext(nn_computer *computer) {
|
||||||
nn_lock(&computer->universe->ctx, computer->lock);
|
return &computer->universe->ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nn_unlockComputer(nn_computer *computer) {
|
nn_guard *nn_getComputerLock(nn_computer *computer) {
|
||||||
nn_unlock(&computer->universe->ctx, computer->lock);
|
return computer->lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nn_return_nil(nn_computer *computer) {
|
void nn_return_nil(nn_computer *computer) {
|
||||||
|
@ -811,8 +811,6 @@ int main(int argc, char **argv) {
|
|||||||
double interval = 1.0/tps;
|
double interval = 1.0/tps;
|
||||||
double totalTime = 0;
|
double totalTime = 0;
|
||||||
|
|
||||||
SetTargetFPS(144);
|
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if(WindowShouldClose()) break;
|
if(WindowShouldClose()) break;
|
||||||
nn_setEnergyInfo(computer, 5000, 5000);
|
nn_setEnergyInfo(computer, 5000, 5000);
|
||||||
|
@ -140,18 +140,6 @@ typedef struct nn_universe nn_universe;
|
|||||||
typedef struct nn_computer nn_computer;
|
typedef struct nn_computer nn_computer;
|
||||||
typedef struct nn_component nn_component;
|
typedef struct nn_component nn_component;
|
||||||
typedef struct nn_componentTable nn_componentTable;
|
typedef struct nn_componentTable nn_componentTable;
|
||||||
typedef struct nn_architecture {
|
|
||||||
void *userdata;
|
|
||||||
const char *archName;
|
|
||||||
void *(*setup)(nn_computer *computer, void *userdata);
|
|
||||||
void (*teardown)(nn_computer *computer, void *state, void *userdata);
|
|
||||||
nn_size_t (*getMemoryUsage)(nn_computer *computer, void *state, void *userdata);
|
|
||||||
void (*tick)(nn_computer *computer, void *state, void *userdata);
|
|
||||||
/* Pointer returned should be allocated with nn_malloc or nn_realloc, so it can be freed with nn_free */
|
|
||||||
char *(*serialize)(nn_computer *computer, void *state, void *userdata, nn_size_t *len);
|
|
||||||
void (*deserialize)(nn_computer *computer, const char *data, nn_size_t len, void *state, void *userdata);
|
|
||||||
} nn_architecture;
|
|
||||||
typedef char *nn_address;
|
|
||||||
|
|
||||||
// A non-zero malloc is a null ptr, with a 0 oldSize, but a non-0 newSize.
|
// A non-zero malloc is a null ptr, with a 0 oldSize, but a non-0 newSize.
|
||||||
// A zero malloc is never called, the proc address itself is returned, which is ignored when freeing.
|
// A zero malloc is never called, the proc address itself is returned, which is ignored when freeing.
|
||||||
@ -164,6 +152,19 @@ typedef struct nn_Alloc {
|
|||||||
nn_AllocProc *proc;
|
nn_AllocProc *proc;
|
||||||
} nn_Alloc;
|
} nn_Alloc;
|
||||||
|
|
||||||
|
typedef struct nn_architecture {
|
||||||
|
void *userdata;
|
||||||
|
const char *archName;
|
||||||
|
void *(*setup)(nn_computer *computer, void *userdata);
|
||||||
|
void (*teardown)(nn_computer *computer, void *state, void *userdata);
|
||||||
|
nn_size_t (*getMemoryUsage)(nn_computer *computer, void *state, void *userdata);
|
||||||
|
void (*tick)(nn_computer *computer, void *state, void *userdata);
|
||||||
|
/* Pointer returned should be allocated with nn_malloc or nn_realloc, so it can be freed with nn_free */
|
||||||
|
char *(*serialize)(nn_computer *computer, nn_Alloc *alloc, void *state, void *userdata, nn_size_t *len);
|
||||||
|
void (*deserialize)(nn_computer *computer, const char *data, nn_size_t len, void *state, void *userdata);
|
||||||
|
} nn_architecture;
|
||||||
|
typedef char *nn_address;
|
||||||
|
|
||||||
#define NN_LOCK_DEFAULT 0
|
#define NN_LOCK_DEFAULT 0
|
||||||
#define NN_LOCK_IMMEDIATE 1
|
#define NN_LOCK_IMMEDIATE 1
|
||||||
|
|
||||||
@ -436,12 +437,12 @@ double nn_getCallCost(nn_computer *computer);
|
|||||||
nn_bool_t nn_isOverworked(nn_computer *computer);
|
nn_bool_t nn_isOverworked(nn_computer *computer);
|
||||||
void nn_triggerIndirect(nn_computer *computer);
|
void nn_triggerIndirect(nn_computer *computer);
|
||||||
|
|
||||||
/* The memory returned can be freed with nn_free() */
|
/* The memory returned can be freed with nn_dealloc() */
|
||||||
char *nn_serializeProgram(nn_computer *computer, nn_size_t *len);
|
char *nn_serializeProgram(nn_computer *computer, nn_Alloc *alloc, nn_size_t *len);
|
||||||
void nn_deserializeProgram(nn_computer *computer, const char *memory, nn_size_t len);
|
void nn_deserializeProgram(nn_computer *computer, const char *memory, nn_size_t len);
|
||||||
|
|
||||||
void nn_lockComputer(nn_computer *computer);
|
nn_Context *nn_getComputerContext(nn_computer *computer);
|
||||||
void nn_unlockComputer(nn_computer *computer);
|
nn_guard *nn_getComputerLock(nn_computer *computer);
|
||||||
|
|
||||||
/// This means the computer has not yet started.
|
/// This means the computer has not yet started.
|
||||||
#define NN_STATE_SETUP 0
|
#define NN_STATE_SETUP 0
|
||||||
@ -1016,10 +1017,10 @@ typedef struct nn_tunnelTable {
|
|||||||
nn_size_t maxValues;
|
nn_size_t maxValues;
|
||||||
nn_size_t maxPacketSize;
|
nn_size_t maxPacketSize;
|
||||||
|
|
||||||
nn_bool_t (*send)(void *userdata, nn_value *values, nn_size_t valueCount);
|
void (*send)(void *userdata, nn_value *values, nn_size_t valueCount, nn_errorbuf_t err);
|
||||||
void (*getChannel)(void *userdata, char *buf, nn_size_t *buflen);
|
nn_size_t (*getChannel)(void *userdata, char *buf, nn_errorbuf_t err);
|
||||||
void (*getWakeMessage)(void *userdata, char *buf, nn_size_t *buflen);
|
nn_size_t (*getWakeMessage)(void *userdata, char *buf, nn_errorbuf_t err);
|
||||||
nn_size_t (*setWakeMessage)(void *userdata, const char *buf, nn_size_t buflen, nn_bool_t fuzzy);
|
nn_size_t (*setWakeMessage)(void *userdata, const char *buf, nn_size_t buflen, nn_bool_t fuzzy, nn_errorbuf_t err);
|
||||||
} nn_tunnelTable;
|
} nn_tunnelTable;
|
||||||
|
|
||||||
typedef struct nn_tunnel nn_tunnel;
|
typedef struct nn_tunnel nn_tunnel;
|
||||||
|
@ -704,7 +704,7 @@ size_t testLuaArch_getMemoryUsage(nn_computer *computer, testLuaArch *arch, void
|
|||||||
return arch->memoryUsed;
|
return arch->memoryUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *testLuaArch_serialize(nn_computer *computer, testLuaArch *arch, void *_, size_t *len) {
|
char *testLuaArch_serialize(nn_computer *computer, nn_Alloc *alloc, testLuaArch *arch, void *_, size_t *len) {
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user