mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
tunnels
This commit is contained in:
parent
b7ddf9c34e
commit
cd02f31368
@ -1,7 +1,59 @@
|
||||
#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_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);
|
||||
}
|
||||
|
@ -42,9 +42,114 @@ void nn_tunnel_destroy(void *_, nn_component *component, nn_tunnel *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) {
|
||||
nn_componentTable *tunnelTable = nn_newComponentTable(nn_getAllocator(universe), "tunnel", NULL, NULL, (nn_componentDestructor *)nn_tunnel_destroy);
|
||||
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) {
|
||||
|
@ -1017,10 +1017,10 @@ typedef struct nn_tunnelTable {
|
||||
nn_size_t maxValues;
|
||||
nn_size_t maxPacketSize;
|
||||
|
||||
nn_bool_t (*send)(void *userdata, nn_value *values, nn_size_t valueCount);
|
||||
void (*getChannel)(void *userdata, char *buf, nn_size_t *buflen);
|
||||
void (*getWakeMessage)(void *userdata, char *buf, nn_size_t *buflen);
|
||||
nn_size_t (*setWakeMessage)(void *userdata, const char *buf, nn_size_t buflen, nn_bool_t fuzzy);
|
||||
void (*send)(void *userdata, nn_value *values, nn_size_t valueCount, nn_errorbuf_t err);
|
||||
nn_size_t (*getChannel)(void *userdata, char *buf, nn_errorbuf_t err);
|
||||
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_errorbuf_t err);
|
||||
} nn_tunnelTable;
|
||||
|
||||
typedef struct nn_tunnel nn_tunnel;
|
||||
|
Loading…
x
Reference in New Issue
Block a user