staggering progress

This commit is contained in:
IonutParau 2025-05-24 16:09:30 +02:00
parent 1f6419a341
commit 542b4340a8
9 changed files with 391 additions and 15 deletions

View File

@ -71,6 +71,10 @@ nn_componentTable *nn_getComponentTable(nn_component *component) {
return component->table; return component->table;
} }
const char *nn_getComponentType(nn_componentTable *table) {
return table->name;
}
void *nn_getComponentUserdata(nn_component *component) { void *nn_getComponentUserdata(nn_component *component) {
return component->statePtr; return component->statePtr;
} }

View File

@ -41,6 +41,9 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
c->userdata = userdata; c->userdata = userdata;
c->memoryTotal = memoryLimit; c->memoryTotal = memoryLimit;
c->tmpAddress = NULL; c->tmpAddress = NULL;
c->temperature = 30;
c->roomTemperature = 30;
c->temperatureCoefficient = 1;
// Setup Architecture // Setup Architecture
c->archState = c->arch->setup(c, c->arch->userdata); c->archState = c->arch->setup(c, c->arch->userdata);
@ -242,6 +245,46 @@ void nn_addEnergy(nn_computer *computer, size_t amount) {
computer->energy += amount; computer->energy += amount;
} }
double nn_getTemperature(nn_computer *computer) {
return computer->temperature;
}
double nn_getThermalCoefficient(nn_computer *computer) {
return computer->temperatureCoefficient;
}
double nn_getRoomTemperature(nn_computer *computer) {
return computer->roomTemperature;
}
void nn_setTemperature(nn_computer *computer, double temperature) {
computer->temperature = temperature;
if(computer->temperature < computer->roomTemperature) computer->temperature = computer->roomTemperature;
}
void nn_setTemperatureCoefficient(nn_computer *computer, double coefficient) {
computer->temperatureCoefficient = coefficient;
}
void nn_setRoomTemperature(nn_computer *computer, double roomTemperature) {
computer->roomTemperature = roomTemperature;
if(computer->temperature < computer->roomTemperature) computer->temperature = computer->roomTemperature;
}
void nn_addHeat(nn_computer *computer, double heat) {
computer->temperature += heat * computer->temperatureCoefficient;
if(computer->temperature < computer->roomTemperature) computer->temperature = computer->roomTemperature;
}
void nn_removeHeat(nn_computer *computer, double heat) {
computer->temperature -= heat * computer->temperatureCoefficient;
if(computer->temperature < computer->roomTemperature) computer->temperature = computer->roomTemperature;
}
bool nn_isOverheating(nn_computer *computer) {
return computer->temperature > NN_OVERHEAT_MIN;
}
const char *nn_getError(nn_computer *computer) { const char *nn_getError(nn_computer *computer) {
return computer->err; return computer->err;
} }
@ -272,7 +315,32 @@ void nn_setCError(nn_computer *computer, const char *err) {
computer->allocatedError = false; computer->allocatedError = false;
} }
nn_component *nn_newComponent(nn_computer *computer, nn_address address, int slot, nn_componentTable *table, void *userdata); nn_component *nn_newComponent(nn_computer *computer, nn_address address, int slot, nn_componentTable *table, void *userdata) {
nn_component *c = NULL;
for(size_t i = 0; i < computer->componentLen; i++) {
if(computer->components[i].address == NULL) {
c = computer->components + i;
break;
}
}
if(c == NULL) {
if(computer->componentLen == computer->componentCap) return NULL; // too many
c = computer->components + computer->componentLen;
computer->componentLen++;
}
c->address = nn_strdup(address);
if(c->address == NULL) return NULL;
c->table = table;
c->slot = slot;
c->computer = computer;
if(table->constructor == NULL) {
c->statePtr = NULL;
} else {
c->statePtr = table->constructor(table->userdata);
}
return c;
}
void nn_removeComponent(nn_computer *computer, nn_address address) { void nn_removeComponent(nn_computer *computer, nn_address address) {
for(size_t i = 0; i < computer->componentLen; i++) { for(size_t i = 0; i < computer->componentLen; i++) {
@ -299,6 +367,21 @@ nn_component *nn_findComponent(nn_computer *computer, nn_address address) {
return NULL; return NULL;
} }
nn_component **nn_listComponent(nn_computer *computer, size_t *len) {
nn_component **c = nn_malloc(sizeof(nn_component *) * computer->componentLen);
if(c == NULL) return NULL;
size_t j = 0;
for(size_t i = 0; i < computer->componentLen; i++) {
nn_component *component = computer->components + i;
if(component->address != NULL) {
c[j] = component;
j++;
}
}
*len = j;
return c;
}
void nn_resetCall(nn_computer *computer) { void nn_resetCall(nn_computer *computer) {
for(size_t i = 0; i < computer->argc; i++) { for(size_t i = 0; i < computer->argc; i++) {
nn_values_drop(computer->args[i]); nn_values_drop(computer->args[i]);

View File

@ -37,6 +37,9 @@ typedef struct nn_computer {
size_t memoryTotal; size_t memoryTotal;
nn_address address; nn_address address;
nn_address tmpAddress; nn_address tmpAddress;
double temperature;
double temperatureCoefficient;
double roomTemperature;
} nn_computer; } nn_computer;
#endif #endif

View File

@ -1,8 +1,18 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "neonucleus.h" #include "neonucleus.h"
#include "testLuaArch.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_cstring(m));
nn_return(computer, nn_values_cstring(m));
nn_return(computer, nn_values_cstring(m));
}
int main() { int main() {
printf("Setting up universe\n"); printf("Setting up universe\n");
nn_universe *universe = nn_newUniverse(); nn_universe *universe = nn_newUniverse();
@ -14,7 +24,23 @@ int main() {
nn_computer *computer = nn_newComputer(universe, "testMachine", arch, NULL, 1*1024*1024, 16); nn_computer *computer = nn_newComputer(universe, "testMachine", arch, NULL, 1*1024*1024, 16);
nn_setEnergyInfo(computer, 5000, 5000); nn_setEnergyInfo(computer, 5000, 5000);
nn_addSupportedArchitecture(computer, arch); nn_addSupportedArchitecture(computer, arch);
nn_componentTable *t = nn_newComponentTable("debugPrint", NULL, NULL, NULL);
nn_defineMethod(t, "log", false, emulator_debugPrint, NULL, "logs stuff");
nn_newComponent(computer, "debugPrint", -1, t, NULL);
double lastTime = nn_realTime();
while(true) { while(true) {
double now = nn_realTime();
double dt = now - lastTime;
if(dt == 0) dt = 1.0/60;
lastTime = now;
// remove some heat per second
nn_removeHeat(computer, dt * (rand() % 12));
if(nn_isOverheating(computer)) continue;
int state = nn_tickComputer(computer); int state = nn_tickComputer(computer);
if(state == NN_STATE_SWITCH) { if(state == NN_STATE_SWITCH) {
nn_architecture *nextArch = nn_getNextArchitecture(computer); nn_architecture *nextArch = nn_getNextArchitecture(computer);

View File

@ -57,6 +57,7 @@
#define NN_MAX_USERDATA 1024 #define NN_MAX_USERDATA 1024
#define NN_MAX_USER_SIZE 128 #define NN_MAX_USER_SIZE 128
#define NN_MAX_SIGNAL_SIZE 8192 #define NN_MAX_SIGNAL_SIZE 8192
#define NN_OVERHEAT_MIN 100
typedef struct nn_guard nn_guard; typedef struct nn_guard nn_guard;
typedef struct nn_universe nn_universe; typedef struct nn_universe nn_universe;
@ -178,37 +179,33 @@ void nn_lockComputer(nn_computer *computer);
void nn_unlockComputer(nn_computer *computer); void nn_unlockComputer(nn_computer *computer);
/// This means the computer has not yet started. /// This means the computer has not yet started.
/// This is used to determine whether newComponent and removeComponent should emit signals.
#define NN_STATE_SETUP 0 #define NN_STATE_SETUP 0
/// This means the computer is running. There is no matching off-state, as the computer is /// This means the computer is running. There is no matching off-state, as the computer is
/// only off when it is deleted. /// only off when it is deleted.
#define NN_STATE_RUNNING 1 #define NN_STATE_RUNNING 1
/// This means a call budget exceeded, and the sandbox should make the computer yield.
#define NN_STATE_OVERUSED 2
/// This means a component's invocation could not be done due to a crucial resource being busy. /// This means a component's invocation could not be done due to a crucial resource being busy.
/// The sandbox should yield, then *invoke the component method again.* /// The sandbox should yield, then *invoke the component method again.*
#define NN_STATE_BUSY 3 #define NN_STATE_BUSY 2
/// This state occurs when a call to removeEnergy has consumed all the energy left. /// This state occurs when a call to removeEnergy has consumed all the energy left.
/// The sandbox should yield, and the runner should shut down the computer. /// The sandbox should yield, and the runner should shut down the computer.
/// No error is set, the sandbox can set it if it wanted to. /// No error is set, the sandbox can set it if it wanted to.
#define NN_STATE_BLACKOUT 4 #define NN_STATE_BLACKOUT 3
/// This state only indicates that the runner should turn off the computer, but not due to a blackout. /// This state only indicates that the runner should turn off the computer, but not due to a blackout.
/// The runner need not bring it back. /// The runner need not bring it back.
#define NN_STATE_CLOSING 5 #define NN_STATE_CLOSING 4
/// This state indicates that the runner should turn off the computer, but not due to a blackout. /// This state indicates that the runner should turn off the computer, but not due to a blackout.
/// The runner should bring it back. /// The runner should bring it back.
/// By "bring it back", we mean delete the computer, then recreate the entire state. /// By "bring it back", we mean delete the computer, then recreate the entire state.
#define NN_STATE_REPEAT 6 #define NN_STATE_REPEAT 5
/// This state indciates that the runner should turn off the computer, to switch architectures. /// This state indciates that the runner should turn off the computer, to switch architectures.
/// The architecture is returned by getNextArchitecture. /// The architecture is returned by getNextArchitecture.
#define NN_STATE_SWITCH 7 #define NN_STATE_SWITCH 6
int nn_getState(nn_computer *computer); int nn_getState(nn_computer *computer);
void nn_setState(nn_computer *computer, int state); void nn_setState(nn_computer *computer, int state);
@ -219,6 +216,17 @@ size_t nn_getMaxEnergy(nn_computer *computer);
void nn_removeEnergy(nn_computer *computer, size_t energy); void nn_removeEnergy(nn_computer *computer, size_t energy);
void nn_addEnergy(nn_computer *computer, size_t amount); void nn_addEnergy(nn_computer *computer, size_t amount);
double nn_getTemperature(nn_computer *computer);
double nn_getThermalCoefficient(nn_computer *computer);
double nn_getRoomTemperature(nn_computer *computer);
void nn_setTemperature(nn_computer *computer, double temperature);
void nn_setTemperatureCoefficient(nn_computer *computer, double coefficient);
void nn_setRoomTemperature(nn_computer *computer, double roomTemperature);
void nn_addHeat(nn_computer *computer, double heat);
void nn_removeHeat(nn_computer *computer, double heat);
/* Checks against NN_OVERHEAT_MIN */
bool nn_isOverheating(nn_computer *computer);
// NULL if there is no error. // NULL if there is no error.
const char *nn_getError(nn_computer *computer); const char *nn_getError(nn_computer *computer);
void nn_clearError(nn_computer *computer); void nn_clearError(nn_computer *computer);
@ -243,8 +251,11 @@ nn_computer *nn_getComputerOfComponent(nn_component *component);
nn_address nn_getComponentAddress(nn_component *component); nn_address nn_getComponentAddress(nn_component *component);
int nn_getComponentSlot(nn_component *component); int nn_getComponentSlot(nn_component *component);
nn_componentTable *nn_getComponentTable(nn_component *component); nn_componentTable *nn_getComponentTable(nn_component *component);
const char *nn_getComponentType(nn_componentTable *table);
void *nn_getComponentUserdata(nn_component *component); void *nn_getComponentUserdata(nn_component *component);
nn_component *nn_findComponent(nn_computer *computer, nn_address address); nn_component *nn_findComponent(nn_computer *computer, nn_address address);
/* RESULT SHOULD BE NN_FREE()'D OR ELSE MEMORY IS LEAKED */
nn_component **nn_listComponent(nn_computer *computer, size_t *len);
// Component VTable stuff // Component VTable stuff

View File

@ -1,5 +1,7 @@
print(string.format("%d / %d", computer.usedMemory(), computer.totalMemory())) print(component.doc("debugPrint", "log"))
print(string.format("Computer Address: %q, Tmp Address: %q", computer.address(), computer.tmpAddress())) local a, b, c = component.invoke("debugPrint", "log", "Absolute cinema")
print(a, b, c)
print(computer.getArchitecture()) computer.pushSignal("stuff", 123, "b", false, nil)
print(table.unpack(computer.getArchitectures()))
print(computer.popSignal())

View File

@ -43,6 +43,78 @@ nn_computer *testLuaArch_getComputer(lua_State *L) {
return testLuaArch_get(L)->computer; return testLuaArch_get(L)->computer;
} }
static nn_value testLuaArch_getValue(lua_State *L, int index) {
if(lua_isinteger(L, index)) {
return nn_values_integer(lua_tointeger(L, index));
}
if(lua_isnumber(L, index)) {
return nn_values_number(lua_tonumber(L, index));
}
if(lua_isboolean(L, index)) {
return nn_values_boolean(lua_toboolean(L, index));
}
if(lua_isnoneornil(L, index)) {
return nn_values_nil();
}
if(lua_isstring(L, index)) {
size_t l = 0;
const char *s = lua_tolstring(L, index, &l);
return nn_values_string(s, l);
}
//TODO: bring it back once I make everything else not leak memory
//luaL_argcheck(L, false, index, luaL_typename(L, index));
return nn_values_nil();
}
static void testLuaArch_pushValue(lua_State *L, nn_value val) {
int t = nn_values_getType(val);
if(t == NN_VALUE_NIL) {
lua_pushnil(L);
return;
}
if(t == NN_VALUE_INT) {
lua_pushinteger(L, val.integer);
return;
}
if(t == NN_VALUE_NUMBER) {
lua_pushnumber(L, val.number);
return;
}
if(t == NN_VALUE_BOOL) {
lua_pushboolean(L, val.boolean);
return;
}
if(t == NN_VALUE_STR) {
lua_pushlstring(L, val.string->data, val.string->len);
return;
}
if(t == NN_VALUE_CSTR) {
lua_pushstring(L, val.cstring);
return;
}
if(t == NN_VALUE_ARRAY) {
nn_array *arr = val.array;
lua_createtable(L, arr->len, 0);
int luaVal = lua_gettop(L);
for(size_t i = 0; i < arr->len; i++) {
testLuaArch_pushValue(L, arr->values[i]);
lua_seti(L, luaVal, i+1);
}
return;
}
if(t == NN_VALUE_TABLE) {
nn_table *tbl = val.table;
lua_createtable(L, 0, tbl->len);
int luaVal = lua_gettop(L);
for(size_t i = 0; i < tbl->len; i++) {
testLuaArch_pushValue(L, tbl->pairs[i].key);
testLuaArch_pushValue(L, tbl->pairs[i].val);
lua_settable(L, luaVal);
}
return;
}
}
static int testLuaArch_computer_usedMemory(lua_State *L) { static int testLuaArch_computer_usedMemory(lua_State *L) {
testLuaArch *s = testLuaArch_get(L); testLuaArch *s = testLuaArch_get(L);
lua_pushinteger(L, s->memoryUsed); lua_pushinteger(L, s->memoryUsed);
@ -133,6 +205,123 @@ static int testLuaArch_computer_setArchitecture(lua_State *L) {
return 0; return 0;
} }
static int testLuaArch_computer_isOverheating(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
lua_pushboolean(L, nn_isOverheating(c));
return 1;
}
static int testLuaArch_computer_getTemperature(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
lua_pushnumber(L, nn_getTemperature(c));
return 1;
}
static int testLuaArch_computer_addHeat(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
double n = luaL_checknumber(L, 1);
nn_addHeat(c, n);
return 0;
}
static int testLuaArch_computer_pushSignal(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
luaL_checkstring(L, 1);
int argc = lua_gettop(L);
if(argc > NN_MAX_ARGS) luaL_error(L, "too many arguments");
nn_value args[argc];
for(size_t i = 0; i < argc; i++) {
args[i] = testLuaArch_getValue(L, i+1);
}
const char *err = nn_pushSignal(c, args, argc);
if(err != NULL) {
for(size_t i = 0; i < argc; i++) {
nn_values_drop(args[i]);
}
luaL_error(L, "%s", err);
return 0;
}
return 0;
}
static int testLuaArch_computer_popSignal(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
size_t retc = nn_signalSize(c);
for(size_t i = 0; i < retc; i++) {
testLuaArch_pushValue(L, nn_fetchSignalValue(c, i));
}
nn_popSignal(c);
return retc;
}
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);
lua_createtable(L, 0, len);
int list = lua_gettop(L);
for(size_t i = 0; i < len; i++) {
nn_component *component = components[i];
nn_componentTable *table = nn_getComponentTable(component);
nn_address addr = nn_getComponentAddress(component);
const char *type = nn_getComponentType(table);
lua_pushstring(L, type);
lua_setfield(L, list, addr);
}
nn_free(components);
return 1;
}
static int testLuaArch_component_doc(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
const char *addr = luaL_checkstring(L, 1);
const char *method = luaL_checkstring(L, 2);
nn_component *component = nn_findComponent(c, (char *)addr);
if(component == NULL) {
lua_pushnil(L);
lua_pushstring(L, "no such component");
return 2;
}
const char *doc = nn_methodDoc(nn_getComponentTable(component), method);
if(doc == NULL) {
lua_pushnil(L);
} else {
lua_pushstring(L, doc);
}
return 1;
}
static int testLuaArch_component_invoke(lua_State *L) {
nn_computer *c = testLuaArch_getComputer(L);
const char *addr = luaL_checkstring(L, 1);
const char *method = luaL_checkstring(L, 2);
int argc = lua_gettop(L) - 2;
nn_component *component = nn_findComponent(c, (char *)addr);
if(component == NULL) {
lua_pushnil(L);
lua_pushstring(L, "no such component");
return 2;
}
nn_resetCall(c);
for(size_t i = 0; i < argc; i++) {
nn_addArgument(c, testLuaArch_getValue(L, 2 + argc));
}
if(!nn_invokeComponentMethod(component, method)) {
nn_resetCall(c);
lua_pushnil(L);
lua_pushstring(L, "no such method");
return 2;
}
size_t retc = nn_getReturnCount(c);
for(size_t i = 0; i < retc; i++) {
testLuaArch_pushValue(L, nn_getReturn(c, i));
}
nn_resetCall(c);
return retc;
}
void testLuaArch_loadEnv(lua_State *L) { void testLuaArch_loadEnv(lua_State *L) {
lua_createtable(L, 0, 10); lua_createtable(L, 0, 10);
int computer = lua_gettop(L); int computer = lua_gettop(L);
@ -148,6 +337,8 @@ void testLuaArch_loadEnv(lua_State *L) {
lua_setfield(L, computer, "tmpAddress"); lua_setfield(L, computer, "tmpAddress");
lua_pushcfunction(L, testLuaArch_computer_uptime); lua_pushcfunction(L, testLuaArch_computer_uptime);
lua_setfield(L, computer, "uptime"); lua_setfield(L, computer, "uptime");
lua_pushcfunction(L, testLuaArch_computer_beep);
lua_setfield(L, computer, "beep");
lua_pushcfunction(L, testLuaArch_computer_energy); lua_pushcfunction(L, testLuaArch_computer_energy);
lua_setfield(L, computer, "energy"); lua_setfield(L, computer, "energy");
lua_pushcfunction(L, testLuaArch_computer_maxEnergy); lua_pushcfunction(L, testLuaArch_computer_maxEnergy);
@ -158,7 +349,23 @@ void testLuaArch_loadEnv(lua_State *L) {
lua_setfield(L, computer, "getArchitectures"); lua_setfield(L, computer, "getArchitectures");
lua_pushcfunction(L, testLuaArch_computer_setArchitecture); lua_pushcfunction(L, testLuaArch_computer_setArchitecture);
lua_setfield(L, computer, "setArchitecture"); lua_setfield(L, computer, "setArchitecture");
lua_pushcfunction(L, testLuaArch_computer_isOverheating);
lua_setfield(L, computer, "isOverheating");
lua_pushcfunction(L, testLuaArch_computer_getTemperature);
lua_setfield(L, computer, "getTemperature");
lua_pushcfunction(L, testLuaArch_computer_addHeat);
lua_setfield(L, computer, "addHeat");
lua_setglobal(L, "computer"); lua_setglobal(L, "computer");
lua_createtable(L, 0, 10);
int component = lua_gettop(L);
lua_pushcfunction(L, testLuaArch_component_list);
lua_setfield(L, component, "list");
lua_pushcfunction(L, testLuaArch_component_doc);
lua_setfield(L, component, "doc");
lua_pushcfunction(L, testLuaArch_component_invoke);
lua_setfield(L, component, "invoke");
lua_setglobal(L, "component");
} }
testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) { testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) {

View File

@ -44,7 +44,6 @@ double nn_realTime() {
#else #else
double nn_realTime() { double nn_realTime() {
LARGE_INTEGER frequency = {0}; LARGE_INTEGER frequency = {0};
if(!QueryPerformanceFrequency(&frequency)) return 0; if(!QueryPerformanceFrequency(&frequency)) return 0;

View File

@ -155,6 +155,47 @@ nn_pair nn_values_getPair(nn_value obj, size_t idx) {
return obj.table->pairs[idx]; return obj.table->pairs[idx];
} }
intptr_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;
}
double nn_toNumber(nn_value val) {
if(val.tag == NN_VALUE_INT) return val.integer;
if(val.tag == NN_VALUE_NUMBER) return val.number;
return 0;
}
bool nn_toBoolean(nn_value val) {
if(val.tag == NN_VALUE_NIL) return false;
if(val.tag == NN_VALUE_BOOL) return val.boolean;
return true;
}
const char *nn_toCString(nn_value val) {
if(val.tag == NN_VALUE_CSTR) return val.cstring;
if(val.tag == NN_VALUE_STR) return val.string->data;
return NULL;
}
const char *nn_toString(nn_value val, size_t *len) {
size_t l = 0;
const char *c = NULL;
if(val.tag == NN_VALUE_CSTR) {
c = val.cstring;
l = strlen(c);
}
if(val.tag == NN_VALUE_STR) {
c = val.string->data;
l = val.string->len;
}
if(len == NULL) *len = l;
return c;
}
size_t nn_measurePacketSize(nn_value *vals, size_t len) { size_t nn_measurePacketSize(nn_value *vals, size_t len) {
size_t size = 0; size_t size = 0;
for(size_t i = 0; i < len; i++) { for(size_t i = 0; i < len; i++) {