mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
eeproms
This commit is contained in:
parent
21b44a71bf
commit
f6f6fb89fd
@ -12,6 +12,8 @@ fn addEngineSources(c: *std.Build.Step.Compile) void {
|
||||
"src/component.c",
|
||||
"src/computer.c",
|
||||
"src/universe.c",
|
||||
// components
|
||||
"src/components/eeprom.c",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
135
src/components/eeprom.c
Normal file
135
src/components/eeprom.c
Normal file
@ -0,0 +1,135 @@
|
||||
#include "../neonucleus.h"
|
||||
|
||||
void nn_eeprom_destroy(void *_, nn_component *component, nn_eeprom *eeprom) {
|
||||
if(atomic_fetch_sub(&eeprom->refc, 1) > 1) return;
|
||||
|
||||
if(eeprom->deinit == NULL) {
|
||||
eeprom->deinit(component, eeprom);
|
||||
}
|
||||
}
|
||||
|
||||
void nn_eeprom_getSize(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_return(computer, nn_values_integer(eeprom->getSize(component, eeprom->userdata)));
|
||||
}
|
||||
|
||||
void nn_eeprom_getDataSize(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_return(computer, nn_values_integer(eeprom->getDataSize(component, eeprom->userdata)));
|
||||
}
|
||||
|
||||
void nn_eeprom_getLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
char buf[NN_LABEL_SIZE];
|
||||
size_t l = NN_LABEL_SIZE;
|
||||
eeprom->getLabel(component, eeprom->userdata, buf, &l);
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
}
|
||||
}
|
||||
|
||||
void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t l = 0;
|
||||
nn_value label = nn_getArgument(computer, 0);
|
||||
const char *buf = nn_toString(label, &l);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "bad label (string expected)");
|
||||
return;
|
||||
}
|
||||
l = eeprom->setLabel(component, eeprom->userdata, buf, l);
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
}
|
||||
|
||||
void nn_eeprom_get(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
size_t len = eeprom->get(component, eeprom->userdata, buf);
|
||||
nn_return(computer, nn_values_string(buf, len));
|
||||
nn_free(buf);
|
||||
}
|
||||
|
||||
void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_value data = nn_getArgument(computer, 0);
|
||||
size_t len;
|
||||
const char *buf = nn_toString(data, &len);
|
||||
if(len > eeprom->getSize(component, eeprom->userdata)) {
|
||||
|
||||
}
|
||||
eeprom->set(component, eeprom->userdata, buf, len);
|
||||
}
|
||||
|
||||
void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
int len = eeprom->getData(component, eeprom->userdata, buf);
|
||||
if(len < 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, len));
|
||||
}
|
||||
nn_free(buf);
|
||||
}
|
||||
|
||||
void nn_eeprom_setData(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_value data = nn_getArgument(computer, 0);
|
||||
size_t len;
|
||||
const char *buf = nn_toString(data, &len);
|
||||
eeprom->setData(component, eeprom->userdata, buf, len);
|
||||
}
|
||||
|
||||
void nn_eeprom_isReadOnly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_return(computer, nn_values_boolean(eeprom->isReadonly(component, eeprom->userdata)));
|
||||
}
|
||||
|
||||
void nn_eeprom_makeReadonly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
eeprom->makeReadonly(component, eeprom->userdata);
|
||||
}
|
||||
|
||||
// TODO: make good
|
||||
void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
size_t len = eeprom->getData(component, eeprom->userdata, buf);
|
||||
size_t sum = 0;
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
nn_free(buf);
|
||||
|
||||
nn_return(computer, nn_values_string((void *)&sum, sizeof(sum)));
|
||||
}
|
||||
|
||||
void nn_loadEepromTable(nn_universe *universe) {
|
||||
nn_componentTable *eepromTable = nn_newComponentTable("eeprom", NULL, NULL, (void *)nn_eeprom_destroy);
|
||||
nn_storeUserdata(universe, "NN:EEPROM", eepromTable);
|
||||
|
||||
nn_defineMethod(eepromTable, "getSize", true, (void *)nn_eeprom_getSize, NULL, "getSize(): integer - Returns the maximum code capacity of the EEPROM.");
|
||||
nn_defineMethod(eepromTable, "getDataSize", true, (void *)nn_eeprom_getDataSize, NULL, "getDataSize(): integer - Returns the maximum data capacity of the EEPROM.");
|
||||
nn_defineMethod(eepromTable, "getLabel", false, (void *)nn_eeprom_getLabel, NULL, "getLabel(): string - Returns the current label.");
|
||||
nn_defineMethod(eepromTable, "setLabel", false, (void *)nn_eeprom_setLabel, NULL, "setLabel(label: string): string - Sets the new label. Returns the actual label set to, which may be truncated.");
|
||||
nn_defineMethod(eepromTable, "get", false, (void *)nn_eeprom_get, NULL, "get(): string - Reads the current code contents.");
|
||||
nn_defineMethod(eepromTable, "set", false, (void *)nn_eeprom_set, NULL, "set(data: string) - Sets the current code contents.");
|
||||
nn_defineMethod(eepromTable, "getData", false, (void *)nn_eeprom_getData, NULL, "getData(): string - Reads the current data contents.");
|
||||
nn_defineMethod(eepromTable, "setData", false, (void *)nn_eeprom_setData, NULL, "setData(data: string) - Sets the current data contents.");
|
||||
nn_defineMethod(eepromTable, "isReadOnly", false, (void *)nn_eeprom_isReadOnly, NULL, "isReadOnly(): boolean - Returns whether this EEPROM is read-only.");
|
||||
nn_defineMethod(eepromTable, "makeReadOnly", false, (void *)nn_eeprom_makeReadonly, NULL, "makeReadOnly() - Makes the current EEPROM read-only. Normally, this cannot be undone.");
|
||||
nn_defineMethod(eepromTable, "makeReadonly", false, (void *)nn_eeprom_makeReadonly, NULL, "makeReadonly() - Legacy alias to makeReadOnly()");
|
||||
nn_defineMethod(eepromTable, "getChecksum", false, (void *)nn_eeprom_getChecksum, NULL, "getChecksum(): string - Returns a checksum of the data on the EEPROM.");
|
||||
}
|
||||
|
||||
nn_component *nn_addEeprom(nn_computer *computer, nn_address address, int slot, nn_eeprom *eeprom) {
|
||||
nn_componentTable *eepromTable = nn_queryUserdata(nn_getUniverse(computer), "NN:EEPROM");
|
||||
|
||||
return nn_newComponent(computer, address, slot, eepromTable, eeprom);
|
||||
}
|
@ -44,6 +44,8 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
|
||||
c->temperature = 30;
|
||||
c->roomTemperature = 30;
|
||||
c->temperatureCoefficient = 1;
|
||||
c->callCost = 0;
|
||||
c->callBudget = 256;
|
||||
|
||||
// Setup Architecture
|
||||
c->archState = c->arch->setup(c, c->arch->userdata);
|
||||
@ -58,6 +60,10 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
|
||||
return c;
|
||||
}
|
||||
|
||||
nn_universe *nn_getUniverse(nn_computer *computer) {
|
||||
return computer->universe;
|
||||
}
|
||||
|
||||
void nn_setTmpAddress(nn_computer *computer, nn_address tmp) {
|
||||
nn_free(computer->tmpAddress);
|
||||
computer->tmpAddress = nn_strdup(tmp);
|
||||
@ -72,6 +78,7 @@ nn_address nn_getTmpAddress(nn_computer *computer) {
|
||||
}
|
||||
|
||||
int nn_tickComputer(nn_computer *computer) {
|
||||
computer->callCost = 0;
|
||||
computer->state = NN_STATE_RUNNING;
|
||||
nn_clearError(computer);
|
||||
computer->arch->tick(computer, computer->archState, computer->arch->userdata);
|
||||
@ -206,6 +213,26 @@ bool nn_isUser(nn_computer *computer, const char *name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void nn_setCallBudget(nn_computer *computer, size_t callBudget) {
|
||||
computer->callBudget = callBudget;
|
||||
}
|
||||
|
||||
size_t nn_getCallBudget(nn_computer *computer) {
|
||||
return computer->callBudget;
|
||||
}
|
||||
|
||||
void nn_callCost(nn_computer *computer, size_t cost) {
|
||||
computer->callCost += cost;
|
||||
}
|
||||
|
||||
size_t nn_getCallCost(nn_computer *computer) {
|
||||
return computer->callCost;
|
||||
}
|
||||
|
||||
bool nn_isOverworked(nn_computer *computer) {
|
||||
return computer->callCost >= computer->callBudget;
|
||||
}
|
||||
|
||||
int nn_getState(nn_computer *computer) {
|
||||
return computer->state;
|
||||
}
|
||||
@ -335,9 +362,9 @@ nn_component *nn_newComponent(nn_computer *computer, nn_address address, int slo
|
||||
c->slot = slot;
|
||||
c->computer = computer;
|
||||
if(table->constructor == NULL) {
|
||||
c->statePtr = NULL;
|
||||
c->statePtr = userdata;
|
||||
} else {
|
||||
c->statePtr = table->constructor(table->userdata);
|
||||
c->statePtr = table->constructor(table->userdata, userdata);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@ -353,7 +380,7 @@ void nn_removeComponent(nn_computer *computer, nn_address address) {
|
||||
void nn_destroyComponent(nn_component *component) {
|
||||
nn_free(component->address);
|
||||
if(component->table->destructor != NULL) {
|
||||
component->table->destructor(component->table->userdata, component->statePtr);
|
||||
component->table->destructor(component->table->userdata, component, component->statePtr);
|
||||
}
|
||||
component->address = NULL; // marks component as freed
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ typedef struct nn_computer {
|
||||
double temperature;
|
||||
double temperatureCoefficient;
|
||||
double roomTemperature;
|
||||
size_t callCost;
|
||||
size_t callBudget;
|
||||
} nn_computer;
|
||||
|
||||
#endif
|
||||
|
@ -4,17 +4,61 @@
|
||||
#include <string.h>
|
||||
#include "neonucleus.h"
|
||||
#include "testLuaArch.h"
|
||||
|
||||
void emulator_debugPrint(void *componentUserdata, void *methodUserdata, nn_component *component, nn_computer *computer) {
|
||||
nn_value msg = nn_getArgument(computer, 0);
|
||||
const char *m = nn_toCString(msg);
|
||||
printf("[DEBUG] %s\n", m);
|
||||
nn_return(computer, nn_values_integer(strlen(m)));
|
||||
|
||||
size_t ne_eeprom_getSize(nn_component *component, void *_) {
|
||||
return 4096;
|
||||
}
|
||||
|
||||
size_t ne_eeprom_getDataSize(nn_component *component, void *_) {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
void ne_eeprom_getLabel(nn_component *component, void *_, char *buf, size_t *buflen) {
|
||||
*buflen = 0;
|
||||
}
|
||||
|
||||
size_t ne_eeprom_setLabel(nn_component *component, void *_, const char *buf, size_t buflen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ne_eeprom_location(nn_address address) {
|
||||
static char buffer[256];
|
||||
snprintf(buffer, 256, "data/%s", address);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
size_t ne_eeprom_get(nn_component *component, void *_, char *buf) {
|
||||
FILE *f = fopen(ne_eeprom_location(nn_getComponentAddress(component)), "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fread(buf, sizeof(char), len, f);
|
||||
fclose(f);
|
||||
return len;
|
||||
}
|
||||
|
||||
void ne_eeprom_set(nn_component *component, void *_, const char *buf, size_t len) {
|
||||
FILE *f = fopen(ne_eeprom_location(nn_getComponentAddress(component)), "wb");
|
||||
fwrite(buf, sizeof(char), len, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int ne_eeprom_getData(nn_component *component, void *_, char *buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ne_eeprom_setData(nn_component *component, void *_, const char *buf, size_t len) {}
|
||||
|
||||
bool ne_eeprom_isReadonly(nn_component *component, void *userdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ne_eeprom_makeReadonly(nn_component *component, void *userdata) {}
|
||||
|
||||
int main() {
|
||||
printf("Setting up universe\n");
|
||||
nn_universe *universe = nn_newUniverse();
|
||||
nn_loadCoreComponentTables(universe);
|
||||
|
||||
nn_architecture *arch = testLuaArch_getArchitecture("src/sandbox.lua");
|
||||
assert(arch != NULL && "Loading architecture failed");
|
||||
@ -24,10 +68,23 @@ int main() {
|
||||
nn_setEnergyInfo(computer, 5000, 5000);
|
||||
nn_addSupportedArchitecture(computer, arch);
|
||||
|
||||
nn_componentTable *t = nn_newComponentTable("debugPrint", NULL, NULL, NULL);
|
||||
nn_defineMethod(t, "log", false, emulator_debugPrint, NULL, "logs stuff");
|
||||
nn_eeprom genericEEPROM = {
|
||||
.userdata = NULL,
|
||||
.refc = 1,
|
||||
.deinit = NULL,
|
||||
.getSize = ne_eeprom_getSize,
|
||||
.getDataSize = ne_eeprom_getDataSize,
|
||||
.getLabel = ne_eeprom_getLabel,
|
||||
.setLabel = ne_eeprom_setLabel,
|
||||
.get = ne_eeprom_get,
|
||||
.set = ne_eeprom_set,
|
||||
.getData = ne_eeprom_getData,
|
||||
.setData = ne_eeprom_setData,
|
||||
.isReadonly = ne_eeprom_isReadonly,
|
||||
.makeReadonly = ne_eeprom_makeReadonly,
|
||||
};
|
||||
|
||||
nn_newComponent(computer, "debugPrint", -1, t, NULL);
|
||||
nn_addEeprom(computer, "luaBios.lua", 0, &genericEEPROM);
|
||||
|
||||
double lastTime = nn_realTime();
|
||||
while(true) {
|
||||
|
@ -13,13 +13,16 @@ nn_guard *nn_newGuard() {
|
||||
}
|
||||
|
||||
void nn_lock(nn_guard *guard) {
|
||||
if(guard == NULL) return;
|
||||
mtx_lock(&guard->m);
|
||||
}
|
||||
|
||||
void nn_unlock(nn_guard *guard) {
|
||||
if(guard == NULL) return;
|
||||
mtx_unlock(&guard->m);
|
||||
}
|
||||
|
||||
void nn_deleteGuard(nn_guard *guard) {
|
||||
if(guard == NULL) return;
|
||||
mtx_destroy(&guard->m);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
// 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__)
|
||||
@ -58,6 +59,9 @@
|
||||
#define NN_MAX_USER_SIZE 128
|
||||
#define NN_MAX_SIGNAL_SIZE 8192
|
||||
#define NN_OVERHEAT_MIN 100
|
||||
#define NN_CALL_HEAT 0.05
|
||||
#define NN_CALL_COST 1
|
||||
#define NN_LABEL_SIZE 128
|
||||
|
||||
typedef struct nn_guard nn_guard;
|
||||
typedef struct nn_universe nn_universe;
|
||||
@ -151,6 +155,7 @@ void nn_setClock(nn_universe *universe, nn_clock_t *clock, void *userdata);
|
||||
double nn_getTime(nn_universe *universe);
|
||||
|
||||
nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, size_t memoryLimit, size_t componentLimit);
|
||||
nn_universe *nn_getUniverse(nn_computer *computer);
|
||||
int nn_tickComputer(nn_computer *computer);
|
||||
double nn_getUptime(nn_computer *computer);
|
||||
size_t nn_getComputerMemoryUsed(nn_computer *computer);
|
||||
@ -170,6 +175,11 @@ const char *nn_addUser(nn_computer *computer, const char *name);
|
||||
void nn_deleteUser(nn_computer *computer, const char *name);
|
||||
const char *nn_indexUser(nn_computer *computer, size_t idx);
|
||||
bool nn_isUser(nn_computer *computer, const char *name);
|
||||
void nn_setCallBudget(nn_computer *computer, size_t callBudget);
|
||||
size_t nn_getCallBudget(nn_computer *computer);
|
||||
void nn_callCost(nn_computer *computer, size_t cost);
|
||||
size_t nn_getCallCost(nn_computer *computer);
|
||||
bool nn_isOverworked(nn_computer *computer);
|
||||
|
||||
/* The memory returned can be freed with nn_free() */
|
||||
char *nn_serializeProgram(nn_computer *computer, size_t *len);
|
||||
@ -259,8 +269,8 @@ nn_component **nn_listComponent(nn_computer *computer, size_t *len);
|
||||
|
||||
// Component VTable stuff
|
||||
|
||||
typedef void *nn_componentConstructor(void *userdata);
|
||||
typedef void *nn_componentDestructor(void *tableUserdata, void *componentUserdata);
|
||||
typedef void *nn_componentConstructor(void *tableUserdata, void *componentUserdata);
|
||||
typedef void *nn_componentDestructor(void *tableUserdata, nn_component *component, void *componentUserdata);
|
||||
typedef void nn_componentMethod(void *componentUserdata, void *methodUserdata, nn_component *component, nn_computer *computer);
|
||||
|
||||
nn_componentTable *nn_newComponentTable(const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor);
|
||||
@ -314,4 +324,34 @@ const char *nn_toString(nn_value val, size_t *len);
|
||||
*/
|
||||
size_t nn_measurePacketSize(nn_value *vals, size_t len);
|
||||
|
||||
// COMPONENTS
|
||||
|
||||
/* Loads the vtables for the default implementations of those components */
|
||||
void nn_loadCoreComponentTables(nn_universe *universe);
|
||||
|
||||
// loading each component
|
||||
void nn_loadEepromTable(nn_universe *universe);
|
||||
|
||||
// the helpers
|
||||
|
||||
// EEPROM
|
||||
typedef struct nn_eeprom {
|
||||
void *userdata;
|
||||
atomic_size_t refc;
|
||||
void (*deinit)(nn_component *component, void *userdata);
|
||||
|
||||
// methods
|
||||
size_t (*getSize)(nn_component *component, void *userdata);
|
||||
size_t (*getDataSize)(nn_component *component, void *userdata);
|
||||
void (*getLabel)(nn_component *component, void *userdata, char *buf, size_t *buflen);
|
||||
size_t (*setLabel)(nn_component *component, void *userdata, const char *buf, size_t buflen);
|
||||
size_t (*get)(nn_component *component, void *userdata, char *buf);
|
||||
void (*set)(nn_component *component, void *userdata, const char *buf, size_t len);
|
||||
int (*getData)(nn_component *component, void *userdata, char *buf);
|
||||
void (*setData)(nn_component *component, void *userdata, const char *buf, size_t len);
|
||||
bool (*isReadonly)(nn_component *component, void *userdata);
|
||||
void (*makeReadonly)(nn_component *component, void *userdata);
|
||||
} nn_eeprom;
|
||||
nn_component *nn_addEeprom(nn_computer *computer, nn_address address, int slot, nn_eeprom *eeprom);
|
||||
|
||||
#endif
|
||||
|
@ -1,11 +1,35 @@
|
||||
print(component.doc("debugPrint", "log"))
|
||||
print(component.invoke("debugPrint", "log", "Absolute cinema"))
|
||||
-- sandbox stuff
|
||||
|
||||
computer.pushSignal("stuff", 123, "a", false, nil)
|
||||
computer.pushSignal("stuf2", 456, "b", true, "shit")
|
||||
computer.pushSignal("stuf3", 789, "c", false, -13)
|
||||
local clist = component.list
|
||||
function component.list(type, exact)
|
||||
local m = clist()
|
||||
if not type then return m end
|
||||
local t = {}
|
||||
for addr, kind in pairs(m) do
|
||||
if exact then
|
||||
if type == kind then
|
||||
t[addr] = kind
|
||||
end
|
||||
else
|
||||
if string.match(kind, type) then
|
||||
t[addr] = kind
|
||||
end
|
||||
end
|
||||
end
|
||||
setmetatable(t, {
|
||||
__call = function()
|
||||
return next(t)
|
||||
end,
|
||||
})
|
||||
return t
|
||||
end
|
||||
|
||||
print(computer.popSignal())
|
||||
print(computer.popSignal())
|
||||
print(computer.popSignal())
|
||||
print(computer.popSignal())
|
||||
for addr, kind in pairs(component.list()) do
|
||||
if kind == "eeprom" then
|
||||
local data = component.invoke(addr, "get")
|
||||
assert(load(data, "=eeprom"))()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
error("no bios")
|
||||
|
@ -254,10 +254,27 @@ static int testLuaArch_computer_popSignal(lua_State *L) {
|
||||
return retc;
|
||||
}
|
||||
|
||||
static int testLuaArch_computer_users(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
size_t i = 0;
|
||||
while(true) {
|
||||
const char *name = nn_indexUser(c, i);
|
||||
if(name == NULL) break;
|
||||
lua_pushstring(L, name);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_list(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
size_t len = 0;
|
||||
nn_component **components = nn_listComponent(c, &len);
|
||||
if(components == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "out of memory");
|
||||
return 2;
|
||||
}
|
||||
lua_createtable(L, 0, len);
|
||||
int list = lua_gettop(L);
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
@ -292,6 +309,62 @@ static int testLuaArch_component_doc(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_fields(lua_State *L) {
|
||||
lua_createtable(L, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_methods(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
const char *addr = luaL_checkstring(L, 1);
|
||||
nn_component *component = nn_findComponent(c, (char *)addr);
|
||||
if(component == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "no such component");
|
||||
return 2;
|
||||
}
|
||||
nn_componentTable *table = nn_getComponentTable(component);
|
||||
lua_createtable(L, 0, 0);
|
||||
int methods = lua_gettop(L);
|
||||
|
||||
size_t i = 0;
|
||||
while(true) {
|
||||
bool direct = false;
|
||||
const char *name = nn_getTableMethod(table, i, &direct);
|
||||
if(name == NULL) break;
|
||||
i++;
|
||||
lua_pushboolean(L, direct);
|
||||
lua_setfield(L, methods, name);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_slot(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
const char *addr = luaL_checkstring(L, 1);
|
||||
nn_component *component = nn_findComponent(c, (char *)addr);
|
||||
if(component == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "no such component");
|
||||
return 2;
|
||||
}
|
||||
lua_pushinteger(L, nn_getComponentSlot(component));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_type(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
const char *addr = luaL_checkstring(L, 1);
|
||||
nn_component *component = nn_findComponent(c, (char *)addr);
|
||||
if(component == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "no such component");
|
||||
return 2;
|
||||
}
|
||||
lua_pushstring(L, nn_getComponentType(nn_getComponentTable(component)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int testLuaArch_component_invoke(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
@ -314,6 +387,10 @@ static int testLuaArch_component_invoke(lua_State *L) {
|
||||
lua_pushstring(L, "no such method");
|
||||
return 2;
|
||||
}
|
||||
if(nn_getError(c) != NULL) {
|
||||
nn_resetCall(c);
|
||||
luaL_error(L, "%s", nn_getError(c));
|
||||
}
|
||||
size_t retc = nn_getReturnCount(c);
|
||||
for(size_t i = 0; i < retc; i++) {
|
||||
testLuaArch_pushValue(L, nn_getReturn(c, i));
|
||||
@ -359,6 +436,8 @@ void testLuaArch_loadEnv(lua_State *L) {
|
||||
lua_setfield(L, computer, "pushSignal");
|
||||
lua_pushcfunction(L, testLuaArch_computer_popSignal);
|
||||
lua_setfield(L, computer, "popSignal");
|
||||
lua_pushcfunction(L, testLuaArch_computer_users);
|
||||
lua_setfield(L, computer, "users");
|
||||
lua_setglobal(L, "computer");
|
||||
|
||||
lua_createtable(L, 0, 10);
|
||||
@ -367,8 +446,16 @@ void testLuaArch_loadEnv(lua_State *L) {
|
||||
lua_setfield(L, component, "list");
|
||||
lua_pushcfunction(L, testLuaArch_component_doc);
|
||||
lua_setfield(L, component, "doc");
|
||||
lua_pushcfunction(L, testLuaArch_component_fields);
|
||||
lua_setfield(L, component, "fields");
|
||||
lua_pushcfunction(L, testLuaArch_component_methods);
|
||||
lua_setfield(L, component, "methods");
|
||||
lua_pushcfunction(L, testLuaArch_component_invoke);
|
||||
lua_setfield(L, component, "invoke");
|
||||
lua_pushcfunction(L, testLuaArch_component_slot);
|
||||
lua_setfield(L, component, "slot");
|
||||
lua_pushcfunction(L, testLuaArch_component_type);
|
||||
lua_setfield(L, component, "type");
|
||||
lua_setglobal(L, "component");
|
||||
}
|
||||
|
||||
|
@ -43,3 +43,7 @@ void nn_storeUserdata(nn_universe *universe, const char *name, void *data) {
|
||||
double nn_getTime(nn_universe *universe) {
|
||||
return universe->currentClock(universe->clockUserdata);
|
||||
}
|
||||
|
||||
void nn_loadCoreComponentTables(nn_universe *universe) {
|
||||
nn_loadEepromTable(universe);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user