mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
Compare commits
3 Commits
faa67f417d
...
af1244b829
Author | SHA1 | Date | |
---|---|---|---|
|
af1244b829 | ||
|
d9670610f8 | ||
|
1bf8604433 |
24
build.zig
24
build.zig
@ -13,7 +13,6 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module {
|
||||
.root_source_file = b.path("src/data.zig"),
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.single_threaded = true,
|
||||
});
|
||||
|
||||
dataMod.addCSourceFiles(.{
|
||||
@ -62,10 +61,17 @@ const LuaVersion = enum {
|
||||
// For the test architecture, we specify the target Lua version we so desire.
|
||||
// This can be checked for with Lua's _VERSION
|
||||
|
||||
fn compileTheRightLua(b: *std.Build, c: *std.Build.Step.Compile, version: LuaVersion) !void {
|
||||
fn compileTheRightLua(b: *std.Build, target: std.Build.ResolvedTarget, version: LuaVersion) !*std.Build.Step.Compile {
|
||||
const alloc = b.allocator;
|
||||
const dirName = @tagName(version);
|
||||
|
||||
const c = b.addObject(.{
|
||||
.name = "lua",
|
||||
.link_libc = true,
|
||||
.optimize = .ReleaseSafe,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const rootPath = try std.mem.join(alloc, std.fs.path.sep_str, &.{ "foreign", dirName });
|
||||
|
||||
c.addIncludePath(b.path(rootPath));
|
||||
@ -90,13 +96,8 @@ fn compileTheRightLua(b: *std.Build, c: *std.Build.Step.Compile, version: LuaVer
|
||||
.root = b.path(rootPath),
|
||||
.files = files.items,
|
||||
});
|
||||
}
|
||||
fn getSharedEngineName(os: std.Target.Os.Tag) []const u8 {
|
||||
if (os == .windows) {
|
||||
return "neonucleusdll";
|
||||
} else {
|
||||
return "neonucleus";
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
@ -125,7 +126,7 @@ pub fn build(b: *std.Build) void {
|
||||
});
|
||||
|
||||
const engineShared = b.addSharedLibrary(.{
|
||||
.name = getSharedEngineName(os),
|
||||
.name = if(os == .windows) "neonucleusdll" else "neonucleus",
|
||||
.root_module = engineMod,
|
||||
});
|
||||
|
||||
@ -167,9 +168,10 @@ pub fn build(b: *std.Build) void {
|
||||
if(opts.bit32) "-DNN_BIT32" else "",
|
||||
},
|
||||
});
|
||||
compileTheRightLua(b, emulator, luaVer) catch unreachable;
|
||||
const l = compileTheRightLua(b, target, luaVer) catch unreachable;
|
||||
|
||||
// forces us to link in everything too
|
||||
emulator.addObject(l);
|
||||
emulator.linkLibrary(engineStatic);
|
||||
|
||||
const emulatorStep = b.step("emulator", "Builds the emulator");
|
||||
|
@ -1,11 +1,53 @@
|
||||
#include "../neonucleus.h"
|
||||
|
||||
nn_eepromControl nn_eeprom_getControl(nn_component *component, nn_eeprom *eeprom) {
|
||||
return eeprom->control(component, eeprom->userdata);
|
||||
typedef struct nn_eeprom {
|
||||
nn_Context ctx;
|
||||
nn_refc refc;
|
||||
nn_guard *lock;
|
||||
nn_eepromTable table;
|
||||
nn_eepromControl control;
|
||||
} nn_eeprom;
|
||||
|
||||
nn_eeprom *nn_newEEPROM(nn_Context *context, nn_eepromTable table, nn_eepromControl control) {
|
||||
nn_eeprom *e = nn_alloc(&context->allocator, sizeof(nn_eeprom));
|
||||
if(e == NULL) return NULL;
|
||||
e->lock = nn_newGuard(context);
|
||||
if(e->lock == NULL) {
|
||||
nn_dealloc(&context->allocator, e, sizeof(nn_eeprom));
|
||||
return NULL;
|
||||
}
|
||||
e->ctx = *context;
|
||||
e->refc = 1;
|
||||
e->control = control;
|
||||
e->table = table;
|
||||
return e;
|
||||
}
|
||||
|
||||
nn_guard *nn_getEEPROMLock(nn_eeprom *eeprom) {
|
||||
return eeprom->lock;
|
||||
}
|
||||
void nn_retainEEPROM(nn_eeprom *eeprom) {
|
||||
nn_incRef(&eeprom->refc);
|
||||
}
|
||||
|
||||
nn_bool_t nn_destroyEEPROM(nn_eeprom *eeprom) {
|
||||
if(!nn_decRef(&eeprom->refc)) return false;
|
||||
// no need to lock, we are the only one with a reference
|
||||
|
||||
if(eeprom->table.deinit != NULL) {
|
||||
eeprom->table.deinit(eeprom->table.userdata);
|
||||
}
|
||||
|
||||
nn_Context ctx = eeprom->ctx;
|
||||
|
||||
nn_deleteGuard(&ctx, eeprom->lock);
|
||||
nn_dealloc(&ctx.allocator, eeprom, sizeof(nn_eeprom));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nn_eeprom_readCost(nn_component *component, nn_size_t bytesRead) {
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, nn_getComponentUserdata(component));
|
||||
nn_eepromControl control = ((nn_eeprom *)nn_getComponentUserdata(component))->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_removeEnergy(computer, control.readEnergyCostPerByte * bytesRead);
|
||||
@ -14,7 +56,7 @@ static void nn_eeprom_readCost(nn_component *component, nn_size_t bytesRead) {
|
||||
}
|
||||
|
||||
static void nn_eeprom_writeCost(nn_component *component, nn_size_t bytesWritten) {
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, nn_getComponentUserdata(component));
|
||||
nn_eepromControl control = ((nn_eeprom *)nn_getComponentUserdata(component))->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_removeEnergy(computer, control.writeEnergyCostPerByte * bytesWritten);
|
||||
@ -23,25 +65,21 @@ static void nn_eeprom_writeCost(nn_component *component, nn_size_t bytesWritten)
|
||||
}
|
||||
|
||||
void nn_eeprom_destroy(void *_, nn_component *component, nn_eeprom *eeprom) {
|
||||
if(!nn_decRef(&eeprom->refc)) return;
|
||||
|
||||
if(eeprom->deinit != NULL) {
|
||||
eeprom->deinit(component, eeprom->userdata);
|
||||
}
|
||||
nn_destroyEEPROM(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)));
|
||||
nn_return(computer, nn_values_integer(eeprom->table.size));
|
||||
}
|
||||
|
||||
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)));
|
||||
nn_return(computer, nn_values_integer(eeprom->table.dataSize));
|
||||
}
|
||||
|
||||
void nn_eeprom_getLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
char buf[NN_LABEL_SIZE];
|
||||
nn_size_t l = NN_LABEL_SIZE;
|
||||
eeprom->getLabel(component, eeprom->userdata, buf, &l);
|
||||
eeprom->table.getLabel(eeprom->table.userdata, buf, &l);
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
@ -60,7 +98,9 @@ void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_
|
||||
nn_setCError(computer, "bad label (string expected)");
|
||||
return;
|
||||
}
|
||||
l = eeprom->setLabel(component, eeprom->userdata, buf, l);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
l = eeprom->table.setLabel(eeprom->table.userdata, buf, l);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
nn_return_string(computer, buf, l);
|
||||
|
||||
// Latency, energy costs and stuff
|
||||
@ -68,14 +108,16 @@ void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_
|
||||
}
|
||||
|
||||
void nn_eeprom_get(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_size_t cap = eeprom->getSize(component, eeprom->userdata);
|
||||
nn_size_t cap = eeprom->table.size;
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
nn_size_t len = eeprom->get(component, eeprom->userdata, buf);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
nn_size_t len = eeprom->table.get(eeprom->table.userdata, buf);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
nn_return_string(computer, buf, len);
|
||||
nn_dealloc(alloc, buf, cap);
|
||||
|
||||
@ -86,7 +128,7 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu
|
||||
nn_value data = nn_getArgument(computer, 0);
|
||||
nn_size_t len;
|
||||
const char *buf = nn_toString(data, &len);
|
||||
if(len > eeprom->getSize(component, eeprom->userdata)) {
|
||||
if(len > eeprom->table.size) {
|
||||
nn_setCError(computer, "out of space");
|
||||
return;
|
||||
}
|
||||
@ -99,20 +141,24 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu
|
||||
return;
|
||||
}
|
||||
}
|
||||
eeprom->set(component, eeprom->userdata, buf, len);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
eeprom->table.set(eeprom->table.userdata, buf, len);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
|
||||
nn_eeprom_writeCost(component, len);
|
||||
}
|
||||
|
||||
void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_size_t cap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
nn_size_t cap = eeprom->table.dataSize;
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
int len = eeprom->getData(component, eeprom->userdata, buf);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
int len = eeprom->table.getData(eeprom->table.userdata, buf);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
if(len < 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
@ -136,42 +182,52 @@ void nn_eeprom_setData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(len > eeprom->getDataSize(component, eeprom->userdata)) {
|
||||
if(len > eeprom->table.dataSize) {
|
||||
nn_setCError(computer, "out of space");
|
||||
return;
|
||||
}
|
||||
eeprom->setData(component, eeprom->userdata, buf, len);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
eeprom->table.setData(eeprom->table.userdata, buf, len);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
|
||||
nn_eeprom_writeCost(component, 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)));
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
nn_return(computer, nn_values_boolean(eeprom->table.isReadonly(eeprom->table.userdata)));
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
}
|
||||
|
||||
void nn_eeprom_makeReadonly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
eeprom->makeReadonly(component, eeprom->userdata);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
eeprom->table.makeReadonly(eeprom->table.userdata);
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
}
|
||||
|
||||
void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_size_t dataCap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
nn_size_t codeCap = eeprom->getSize(component, eeprom->userdata);
|
||||
nn_size_t dataCap = eeprom->table.dataSize;
|
||||
nn_size_t codeCap = eeprom->table.size;
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, dataCap + codeCap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
int dataLen = eeprom->getData(component, eeprom->userdata, buf);
|
||||
nn_lock(&eeprom->ctx, eeprom->lock);
|
||||
int dataLen = eeprom->table.getData(eeprom->table.userdata, buf);
|
||||
if(dataLen < 0) {
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
nn_dealloc(alloc, buf, dataCap + codeCap);
|
||||
return;
|
||||
}
|
||||
int codeLen = eeprom->get(component, eeprom->userdata, buf + dataLen);
|
||||
int codeLen = eeprom->table.get(eeprom->table.userdata, buf + dataLen);
|
||||
if(codeLen < 0) {
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
nn_dealloc(alloc, buf, dataCap + codeCap);
|
||||
return;
|
||||
}
|
||||
nn_unlock(&eeprom->ctx, eeprom->lock);
|
||||
char hash[4];
|
||||
nn_data_crc32(buf, dataLen + codeLen, hash);
|
||||
nn_dealloc(alloc, buf, dataCap + codeCap);
|
||||
|
@ -1,11 +1,88 @@
|
||||
#include "../neonucleus.h"
|
||||
|
||||
void nn_fs_destroy(void *_, nn_component *component, nn_filesystem *fs) {
|
||||
if(!nn_decRef(&fs->refc)) return;
|
||||
typedef struct nn_filesystem {
|
||||
nn_refc refc;
|
||||
nn_guard *lock;
|
||||
nn_Context ctx;
|
||||
nn_filesystemTable table;
|
||||
nn_filesystemControl control;
|
||||
nn_size_t spaceUsedCache;
|
||||
|
||||
if(fs->deinit != NULL) {
|
||||
fs->deinit(component, fs->userdata);
|
||||
// last due to cache concerns (this struck is massive)
|
||||
void *files[NN_MAX_OPEN_FILES];
|
||||
} nn_filesystem;
|
||||
|
||||
void nn_fs_destroy(void *_, nn_component *component, nn_filesystem *fs) {
|
||||
nn_destroyFilesystem(fs);
|
||||
}
|
||||
|
||||
nn_filesystem *nn_newFilesystem(nn_Context *context, nn_filesystemTable table, nn_filesystemControl control) {
|
||||
nn_filesystem *fs = nn_alloc(&context->allocator, sizeof(nn_filesystem));
|
||||
if(fs == NULL) return NULL;
|
||||
fs->refc = 1;
|
||||
fs->ctx = *context;
|
||||
fs->table = table;
|
||||
fs->control = control;
|
||||
fs->spaceUsedCache = 0;
|
||||
fs->lock = nn_newGuard(context);
|
||||
if(fs->lock == NULL) {
|
||||
nn_dealloc(&context->allocator, fs, sizeof(nn_filesystem));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(nn_size_t i = 0; i < NN_MAX_OPEN_FILES; i++) {
|
||||
fs->files[i] = NULL;
|
||||
}
|
||||
return fs;
|
||||
}
|
||||
|
||||
nn_guard *nn_getFilesystemLock(nn_filesystem *fs) {
|
||||
return fs->lock;
|
||||
}
|
||||
|
||||
void nn_retainFilesystem(nn_filesystem *fs) {
|
||||
nn_incRef(&fs->refc);
|
||||
}
|
||||
|
||||
nn_bool_t nn_destroyFilesystem(nn_filesystem *fs) {
|
||||
if(!nn_decRef(&fs->refc)) return false;
|
||||
|
||||
if(fs->table.deinit != NULL) {
|
||||
fs->table.deinit(fs->table.userdata);
|
||||
}
|
||||
|
||||
nn_Context ctx = fs->ctx;
|
||||
nn_deleteGuard(&ctx, fs->lock);
|
||||
nn_dealloc(&ctx.allocator, fs, sizeof(nn_filesystem));
|
||||
return true;
|
||||
}
|
||||
|
||||
nn_size_t nn_fs_getSpaceUsed(nn_filesystem *fs) {
|
||||
if(fs->spaceUsedCache != 0) return fs->spaceUsedCache;
|
||||
nn_size_t spaceUsed = fs->table.spaceUsed(fs->table.userdata);
|
||||
fs->spaceUsedCache = spaceUsed;
|
||||
return spaceUsed;
|
||||
}
|
||||
|
||||
void nn_fs_invalidateSpaceUsed(nn_filesystem *fs) {
|
||||
fs->spaceUsedCache = 0;
|
||||
}
|
||||
|
||||
nn_size_t nn_fs_getSpaceRemaining(nn_filesystem *fs) {
|
||||
nn_size_t used = nn_fs_getSpaceUsed(fs);
|
||||
nn_size_t total = fs->table.spaceTotal;
|
||||
return total - used;
|
||||
}
|
||||
|
||||
void *nn_fs_unwrapFD(nn_filesystem *fs, nn_size_t fd) {
|
||||
if(fd >= NN_MAX_OPEN_FILES) {
|
||||
return NULL;
|
||||
}
|
||||
void *file = fs->files[fd];
|
||||
if(file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
nn_bool_t nn_fs_illegalPath(const char *path) {
|
||||
@ -18,12 +95,8 @@ nn_bool_t nn_fs_illegalPath(const char *path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nn_filesystemControl nn_fs_getControl(nn_component *component, nn_filesystem *fs) {
|
||||
return fs->control(component, fs->userdata);
|
||||
}
|
||||
|
||||
void nn_fs_readCost(nn_filesystem *fs, nn_size_t bytes, nn_component *component) {
|
||||
nn_filesystemControl control = nn_fs_getControl(component, fs);
|
||||
nn_filesystemControl control = fs->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_simulateBufferedIndirect(component, bytes, control.readBytesPerTick);
|
||||
@ -32,7 +105,7 @@ void nn_fs_readCost(nn_filesystem *fs, nn_size_t bytes, nn_component *component)
|
||||
}
|
||||
|
||||
void nn_fs_writeCost(nn_filesystem *fs, nn_size_t bytes, nn_component *component) {
|
||||
nn_filesystemControl control = nn_fs_getControl(component, fs);
|
||||
nn_filesystemControl control = fs->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_simulateBufferedIndirect(component, bytes, control.writeBytesPerTick);
|
||||
@ -41,7 +114,7 @@ void nn_fs_writeCost(nn_filesystem *fs, nn_size_t bytes, nn_component *component
|
||||
}
|
||||
|
||||
void nn_fs_removeCost(nn_filesystem *fs, nn_size_t count, nn_component *component) {
|
||||
nn_filesystemControl control = nn_fs_getControl(component, fs);
|
||||
nn_filesystemControl control = fs->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_simulateBufferedIndirect(component, count, control.removeFilesPerTick);
|
||||
@ -50,7 +123,7 @@ void nn_fs_removeCost(nn_filesystem *fs, nn_size_t count, nn_component *componen
|
||||
}
|
||||
|
||||
void nn_fs_createCost(nn_filesystem *fs, nn_size_t count, nn_component *component) {
|
||||
nn_filesystemControl control = nn_fs_getControl(component, fs);
|
||||
nn_filesystemControl control = fs->control;
|
||||
nn_computer *computer = nn_getComputerOfComponent(component);
|
||||
|
||||
nn_simulateBufferedIndirect(component, count, control.createFilesPerTick);
|
||||
@ -61,7 +134,7 @@ void nn_fs_createCost(nn_filesystem *fs, nn_size_t count, nn_component *componen
|
||||
void nn_fs_getLabel(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
char buf[NN_LABEL_SIZE];
|
||||
nn_size_t l = NN_LABEL_SIZE;
|
||||
fs->getLabel(component, fs->userdata, buf, &l);
|
||||
fs->table.getLabel(fs->table.userdata, buf, &l);
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
@ -79,24 +152,23 @@ void nn_fs_setLabel(nn_filesystem *fs, void *_, nn_component *component, nn_comp
|
||||
nn_setCError(computer, "bad label (string expected)");
|
||||
return;
|
||||
}
|
||||
l = fs->setLabel(component, fs->userdata, buf, l);
|
||||
l = fs->table.setLabel(fs->table.userdata, buf, l);
|
||||
nn_return_string(computer, buf, l);
|
||||
|
||||
nn_fs_writeCost(fs, l, component);
|
||||
}
|
||||
|
||||
void nn_fs_spaceUsed(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_size_t space = fs->spaceUsed(component, fs->userdata);
|
||||
nn_size_t space = nn_fs_getSpaceUsed(fs);
|
||||
nn_return(computer, nn_values_integer(space));
|
||||
}
|
||||
|
||||
void nn_fs_spaceTotal(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_size_t space = fs->spaceUsed(component, fs->userdata);
|
||||
nn_return(computer, nn_values_integer(space));
|
||||
nn_return(computer, nn_values_integer(fs->table.spaceTotal));
|
||||
}
|
||||
|
||||
void nn_fs_isReadOnly(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_return(computer, nn_values_boolean(fs->isReadOnly(component, fs->userdata)));
|
||||
nn_return_boolean(computer, fs->table.isReadOnly(fs->table.userdata));
|
||||
}
|
||||
|
||||
void nn_fs_size(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -111,7 +183,7 @@ void nn_fs_size(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
return;
|
||||
}
|
||||
|
||||
nn_size_t byteSize = fs->size(component, fs->userdata, path);
|
||||
nn_size_t byteSize = fs->table.size(fs->table.userdata, path);
|
||||
|
||||
nn_return(computer, nn_values_integer(byteSize));
|
||||
}
|
||||
@ -128,9 +200,10 @@ void nn_fs_remove(nn_filesystem *fs, void *_, nn_component *component, nn_comput
|
||||
return;
|
||||
}
|
||||
|
||||
nn_return(computer, nn_values_boolean(fs->remove(component, fs->userdata, path)));
|
||||
nn_size_t removed = fs->table.remove(fs->table.userdata, path);
|
||||
nn_return_boolean(computer, removed > 0);
|
||||
|
||||
nn_fs_removeCost(fs, 1, component);
|
||||
nn_fs_removeCost(fs, removed, component);
|
||||
}
|
||||
|
||||
void nn_fs_lastModified(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -145,7 +218,7 @@ void nn_fs_lastModified(nn_filesystem *fs, void *_, nn_component *component, nn_
|
||||
return;
|
||||
}
|
||||
|
||||
nn_size_t t = fs->lastModified(component, fs->userdata, path);
|
||||
nn_size_t t = fs->table.lastModified(fs->table.userdata, path);
|
||||
|
||||
// OpenOS does BULLSHIT with this thing, dividing it by 1000 and expecting it to be
|
||||
// fucking usable as a date, meaning it needs to be an int.
|
||||
@ -178,7 +251,7 @@ void nn_fs_rename(nn_filesystem *fs, void *_, nn_component *component, nn_comput
|
||||
return;
|
||||
}
|
||||
|
||||
nn_size_t movedCount = fs->rename(component, fs->userdata, from, to);
|
||||
nn_size_t movedCount = fs->table.rename(fs->table.userdata, from, to);
|
||||
nn_return(computer, nn_values_boolean(movedCount > 0));
|
||||
|
||||
nn_fs_removeCost(fs, movedCount, component);
|
||||
@ -197,7 +270,7 @@ void nn_fs_exists(nn_filesystem *fs, void *_, nn_component *component, nn_comput
|
||||
return;
|
||||
}
|
||||
|
||||
nn_return(computer, nn_values_boolean(fs->exists(component, fs->userdata, path)));
|
||||
nn_return_boolean(computer, fs->table.exists(fs->table.userdata, path));
|
||||
}
|
||||
|
||||
void nn_fs_isDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -212,7 +285,7 @@ void nn_fs_isDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_c
|
||||
return;
|
||||
}
|
||||
|
||||
nn_return(computer, nn_values_boolean(fs->isDirectory(component, fs->userdata, path)));
|
||||
nn_return_boolean(computer, fs->table.isDirectory(fs->table.userdata, path));
|
||||
}
|
||||
|
||||
void nn_fs_makeDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -227,7 +300,7 @@ void nn_fs_makeDirectory(nn_filesystem *fs, void *_, nn_component *component, nn
|
||||
return;
|
||||
}
|
||||
|
||||
nn_return(computer, nn_values_boolean(fs->makeDirectory(component, fs->userdata, path)));
|
||||
nn_return_boolean(computer, fs->table.makeDirectory(fs->table.userdata, path));
|
||||
|
||||
nn_fs_createCost(fs, 1, component);
|
||||
}
|
||||
@ -247,7 +320,7 @@ void nn_fs_list(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
|
||||
nn_size_t fileCount = 0;
|
||||
char **files = fs->list(alloc, component, fs->userdata, path, &fileCount);
|
||||
char **files = fs->table.list(alloc, fs->table.userdata, path, &fileCount);
|
||||
|
||||
if(files != NULL) {
|
||||
// operation succeeded
|
||||
@ -280,19 +353,40 @@ void nn_fs_open(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
}
|
||||
|
||||
// technically wrongfully
|
||||
if(!fs->exists(component, fs->userdata, path)) {
|
||||
if(!fs->table.exists(fs->table.userdata, path)) {
|
||||
nn_fs_createCost(fs, 1, component);
|
||||
}
|
||||
|
||||
nn_size_t fd = fs->open(component, fs->userdata, path, mode);
|
||||
nn_size_t fd = 0;
|
||||
while(fs->files[fd] != NULL) {
|
||||
fd++;
|
||||
if(fd == NN_MAX_OPEN_FILES) {
|
||||
nn_setCError(computer, "too many open files");
|
||||
return;
|
||||
}
|
||||
}
|
||||
void *file = fs->table.open(fs->table.userdata, path, mode);
|
||||
if(file == NULL) {
|
||||
nn_setCError(computer, "no such file or directory");
|
||||
return;
|
||||
}
|
||||
fs->files[fd] = file;
|
||||
nn_return(computer, nn_values_integer(fd));
|
||||
}
|
||||
|
||||
void nn_fs_close(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_value fdValue = nn_getArgument(computer, 0);
|
||||
nn_size_t fd = nn_toInt(fdValue);
|
||||
void *file = nn_fs_unwrapFD(fs, fd);
|
||||
if(file == NULL) {
|
||||
nn_setCError(computer, "bad file descriptor");
|
||||
return;
|
||||
}
|
||||
|
||||
nn_bool_t closed = fs->close(component, fs->userdata, fd);
|
||||
nn_bool_t closed = fs->table.close(fs->table.userdata, file);
|
||||
if(closed) {
|
||||
fs->files[fd] = NULL;
|
||||
}
|
||||
nn_return(computer, nn_values_boolean(closed));
|
||||
}
|
||||
|
||||
@ -300,8 +394,6 @@ void nn_fs_write(nn_filesystem *fs, void *_, nn_component *component, nn_compute
|
||||
nn_value fdValue = nn_getArgument(computer, 0);
|
||||
nn_size_t fd = nn_toInt(fdValue);
|
||||
|
||||
// size_t spaceRemaining = fs->spaceTotal(component, fs->userdata) - fs->spaceUsed(component, fs->userdata);
|
||||
|
||||
nn_value bufferValue = nn_getArgument(computer, 1);
|
||||
nn_size_t len = 0;
|
||||
const char *buf = nn_toString(bufferValue, &len);
|
||||
@ -310,11 +402,24 @@ void nn_fs_write(nn_filesystem *fs, void *_, nn_component *component, nn_compute
|
||||
return;
|
||||
}
|
||||
|
||||
nn_bool_t closed = fs->write(component, fs->userdata, fd, buf, len);
|
||||
nn_return(computer, nn_values_boolean(closed));
|
||||
size_t spaceRemaining = nn_fs_getSpaceRemaining(fs);
|
||||
|
||||
// overwriting would still work but OC does the same thing so...
|
||||
if(spaceRemaining < len) {
|
||||
nn_setCError(computer, "out of space");
|
||||
return;
|
||||
}
|
||||
void *file = nn_fs_unwrapFD(fs, fd);
|
||||
if(file == NULL) {
|
||||
nn_setCError(computer, "bad file descriptor");
|
||||
return;
|
||||
}
|
||||
|
||||
nn_bool_t written = fs->table.write(fs->table.userdata, file, buf, len);
|
||||
nn_return(computer, nn_values_boolean(written));
|
||||
if(written) nn_fs_invalidateSpaceUsed(fs);
|
||||
|
||||
nn_fs_writeCost(fs, len, component);
|
||||
nn_return_boolean(computer, true);
|
||||
}
|
||||
|
||||
void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -323,10 +428,17 @@ void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
|
||||
nn_value lenValue = nn_getArgument(computer, 1);
|
||||
double len = nn_toNumber(lenValue);
|
||||
nn_size_t capacity = fs->spaceTotal(component, fs->userdata);
|
||||
// TODO: be smarter
|
||||
nn_size_t capacity = fs->table.spaceTotal;
|
||||
if(len > capacity) len = capacity;
|
||||
nn_size_t byteLen = len;
|
||||
|
||||
void *file = nn_fs_unwrapFD(fs, fd);
|
||||
if(file == NULL) {
|
||||
nn_setCError(computer, "bad file descriptor");
|
||||
return;
|
||||
}
|
||||
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, byteLen);
|
||||
if(buf == NULL) {
|
||||
@ -334,7 +446,7 @@ void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
return;
|
||||
}
|
||||
|
||||
nn_size_t readLen = fs->read(component, fs->userdata, fd, buf, byteLen);
|
||||
nn_size_t readLen = fs->table.read(fs->table.userdata, file, buf, byteLen);
|
||||
if(readLen > 0) {
|
||||
// Nothing read means EoF.
|
||||
nn_return_string(computer, buf, readLen);
|
||||
@ -368,11 +480,13 @@ void nn_fs_seek(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
return;
|
||||
}
|
||||
|
||||
// size_t capacity = fs->spaceTotal(component, fs->userdata);
|
||||
int moved = 0;
|
||||
void *file = nn_fs_unwrapFD(fs, fd);
|
||||
if(file == NULL) {
|
||||
nn_setCError(computer, "bad file descriptor");
|
||||
return;
|
||||
}
|
||||
|
||||
nn_size_t pos = fs->seek(component, fs->userdata, fd, whence, off, &moved);
|
||||
if(moved < 0) moved = -moved;
|
||||
nn_size_t pos = fs->table.seek(fs->table.userdata, file, whence, off);
|
||||
|
||||
nn_return_integer(computer, pos);
|
||||
}
|
||||
|
@ -164,9 +164,9 @@ void nni_gpu_get(nni_gpu *gpu, void *_, nn_component *component, nn_computer *co
|
||||
nn_unicode_codepointToChar(chr, pxl.codepoint, &l);
|
||||
|
||||
// TODO: gosh darn palettes
|
||||
nn_return(computer, nn_values_cstring(chr));
|
||||
nn_return(computer, nn_values_integer(pxl.fg));
|
||||
nn_return(computer, nn_values_integer(pxl.bg));
|
||||
nn_return_string(computer, chr, l);
|
||||
nn_return_integer(computer, pxl.fg);
|
||||
nn_return_integer(computer, pxl.bg);
|
||||
}
|
||||
|
||||
void nni_gpu_getScreen(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) {
|
||||
|
198
src/emulator.c
198
src/emulator.c
@ -96,30 +96,20 @@ Color ne_processColor(unsigned int color) {
|
||||
return GetColor(color);
|
||||
}
|
||||
|
||||
nn_eepromControl ne_eeprom_getControl(nn_component *component, void *_) {
|
||||
return (nn_eepromControl) {
|
||||
.readHeatPerByte = 0.0015,
|
||||
.writeHeatPerByte = 0.03,
|
||||
.readEnergyCostPerByte = 0.001,
|
||||
.writeEnergyCostPerByte = 0.05,
|
||||
.bytesReadPerTick = 32768,
|
||||
.bytesWrittenPerTick = 4096,
|
||||
};
|
||||
}
|
||||
nn_eepromControl ne_eeprom_ctrl = {
|
||||
.readHeatPerByte = 0.0015,
|
||||
.writeHeatPerByte = 0.03,
|
||||
.readEnergyCostPerByte = 0.001,
|
||||
.writeEnergyCostPerByte = 0.05,
|
||||
.bytesReadPerTick = 32768,
|
||||
.bytesWrittenPerTick = 4096,
|
||||
};
|
||||
|
||||
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) {
|
||||
void ne_eeprom_getLabel(void *_, char *buf, size_t *buflen) {
|
||||
*buflen = 0;
|
||||
}
|
||||
|
||||
size_t ne_eeprom_setLabel(nn_component *component, void *_, const char *buf, size_t buflen) {
|
||||
size_t ne_eeprom_setLabel(void *_, const char *buf, size_t buflen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -129,8 +119,8 @@ const char *ne_location(nn_address address) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
size_t ne_eeprom_get(nn_component *component, void *_, char *buf) {
|
||||
FILE *f = fopen(ne_location(nn_getComponentAddress(component)), "rb");
|
||||
size_t ne_eeprom_get(void *addr, char *buf) {
|
||||
FILE *f = fopen(ne_location(addr), "rb");
|
||||
if (f == NULL) {
|
||||
printf("couldn't read eeprom");
|
||||
exit(1);
|
||||
@ -143,8 +133,8 @@ size_t ne_eeprom_get(nn_component *component, void *_, char *buf) {
|
||||
return len;
|
||||
}
|
||||
|
||||
void ne_eeprom_set(nn_component *component, void *_, const char *buf, size_t len) {
|
||||
FILE *f = fopen(ne_location(nn_getComponentAddress(component)), "wb");
|
||||
void ne_eeprom_set(void *addr, const char *buf, size_t len) {
|
||||
FILE *f = fopen(ne_location(addr), "wb");
|
||||
if (f == NULL) {
|
||||
printf("couldn't write eeprom");
|
||||
exit(1);
|
||||
@ -153,55 +143,50 @@ void ne_eeprom_set(nn_component *component, void *_, const char *buf, size_t len
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int ne_eeprom_getData(nn_component *component, void *_, char *buf) {
|
||||
int ne_eeprom_getData(void *_, char *buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ne_eeprom_setData(nn_component *component, void *_, const char *buf, size_t len) {}
|
||||
void ne_eeprom_setData(void *_, const char *buf, size_t len) {}
|
||||
|
||||
nn_bool_t ne_eeprom_isReadonly(nn_component *component, void *userdata) {
|
||||
nn_bool_t ne_eeprom_isReadonly(void *userdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ne_eeprom_makeReadonly(nn_component *component, void *userdata) {}
|
||||
void ne_eeprom_makeReadonly(void *userdata) {}
|
||||
|
||||
#define NE_FS_MAX 128
|
||||
nn_filesystemControl ne_fs_ctrl = {
|
||||
.readBytesPerTick = 65536,
|
||||
.writeBytesPerTick = 32768,
|
||||
.removeFilesPerTick = 16,
|
||||
.createFilesPerTick = 16,
|
||||
|
||||
typedef struct ne_fs {
|
||||
FILE *files[NE_FS_MAX];
|
||||
size_t fileLen;
|
||||
} ne_fs;
|
||||
.readHeatPerByte = 0.0000015,
|
||||
.writeHeatPerByte = 0.000015,
|
||||
.removeHeat = 0.035,
|
||||
.createHeat = 0.045,
|
||||
|
||||
nn_filesystemControl ne_fs_getControl(nn_component *component, ne_fs *_) {
|
||||
return (nn_filesystemControl) {
|
||||
.readBytesPerTick = 65536,
|
||||
.writeBytesPerTick = 32768,
|
||||
.removeFilesPerTick = 16,
|
||||
.createFilesPerTick = 16,
|
||||
.readEnergyPerByte = 0.0015,
|
||||
.writeEnergyPerByte = 0.0035,
|
||||
.removeEnergy = 0.135,
|
||||
.createEnergy = 0.325,
|
||||
};
|
||||
|
||||
.readHeatPerByte = 0.0000015,
|
||||
.writeHeatPerByte = 0.000015,
|
||||
.removeHeat = 0.035,
|
||||
.createHeat = 0.045,
|
||||
|
||||
.readEnergyPerByte = 0.0015,
|
||||
.writeEnergyPerByte = 0.0035,
|
||||
.removeEnergy = 0.135,
|
||||
.createEnergy = 0.325,
|
||||
};
|
||||
void ne_fs_getLabel(nn_component *component, void *_, char *buf, size_t *buflen) {
|
||||
*buflen = 0;
|
||||
}
|
||||
|
||||
size_t ne_fs_spaceUsed(nn_component *component, void *_) {
|
||||
nn_size_t ne_fs_setLabel(nn_component *component, void *_, const char *buf, size_t buflen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ne_fs_spaceUsed(void *_) {
|
||||
return 0; // ultra accurate
|
||||
}
|
||||
|
||||
size_t ne_fs_spaceTotal(nn_component *component, void *_) {
|
||||
return 1*1024*1024;
|
||||
}
|
||||
|
||||
const char *ne_fs_diskPath(nn_component *component, const char *path) {
|
||||
const char *ne_fs_diskPath(nn_address addr, const char *path) {
|
||||
static char buf[256];
|
||||
const char *root = ne_location(nn_getComponentAddress(component));
|
||||
const char *root = ne_location(addr);
|
||||
if(path[0] == '/') {
|
||||
snprintf(buf, 256, "%s%s", root, path);
|
||||
} else {
|
||||
@ -211,12 +196,7 @@ const char *ne_fs_diskPath(nn_component *component, const char *path) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
size_t ne_fs_open(nn_component *component, ne_fs *fs, const char *path, const char *mode) {
|
||||
if(fs->fileLen == NE_FS_MAX) {
|
||||
nn_setCError(nn_getComputerOfComponent(component), "too many files");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *ne_fs_open(nn_address address, const char *path, const char *mode) {
|
||||
const char *trueMode = "rb";
|
||||
if(strcmp(mode, "w") == 0) {
|
||||
trueMode = "wb";
|
||||
@ -225,48 +205,27 @@ size_t ne_fs_open(nn_component *component, ne_fs *fs, const char *path, const ch
|
||||
trueMode = "ab";
|
||||
}
|
||||
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
const char *p = ne_fs_diskPath(address, path);
|
||||
if(p[0] == '/') p++;
|
||||
FILE *f = fopen(p, trueMode);
|
||||
|
||||
if(f == NULL) {
|
||||
nn_setCError(nn_getComputerOfComponent(component), strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < fs->fileLen; i++) {
|
||||
if(fs->files[i] == NULL) {
|
||||
fs->files[i] = f;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
size_t i = fs->fileLen++;
|
||||
fs->files[i] = f;
|
||||
return i;
|
||||
return f;
|
||||
}
|
||||
|
||||
bool ne_fs_close(nn_component *component, ne_fs *fs, int fd) {
|
||||
// we pray
|
||||
fclose(fs->files[fd]);
|
||||
fs->files[fd] = NULL;
|
||||
bool ne_fs_close(nn_address addr, FILE *f) {
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ne_fs_write(nn_component *component, ne_fs *fs, int fd, const char *buf, size_t len) {
|
||||
FILE *f = fs->files[fd];
|
||||
bool ne_fs_write(nn_address addr, FILE *f, const char *buf, size_t len) {
|
||||
return fwrite(buf, sizeof(char), len, f) > 0;
|
||||
}
|
||||
|
||||
size_t ne_fs_read(nn_component *component, ne_fs *fs, int fd, char *buf, size_t required) {
|
||||
FILE *f = fs->files[fd];
|
||||
size_t ne_fs_read(nn_address addr, FILE *f, char *buf, size_t required) {
|
||||
if(feof(f)) return 0;
|
||||
return fread(buf, sizeof(char), required, f);
|
||||
}
|
||||
|
||||
size_t ne_fs_seek(nn_component *component, ne_fs *fs, int fd, const char *whence, int off, int *moved) {
|
||||
FILE *f = fs->files[fd];
|
||||
*moved = 0;
|
||||
size_t ne_fs_seek(nn_address addr, FILE *f, const char *whence, int off) {
|
||||
int w = SEEK_SET;
|
||||
if(strcmp(whence, "cur") == 0) {
|
||||
w = SEEK_CUR;
|
||||
@ -278,8 +237,8 @@ size_t ne_fs_seek(nn_component *component, ne_fs *fs, int fd, const char *whence
|
||||
return ftell(f);
|
||||
}
|
||||
|
||||
char **ne_fs_list(nn_Alloc *alloc, nn_component *component, ne_fs *fs, const char *path, size_t *len) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
char **ne_fs_list(nn_Alloc *alloc, nn_address addr, const char *path, size_t *len) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
FilePathList files = LoadDirectoryFiles(p);
|
||||
@ -295,8 +254,8 @@ char **ne_fs_list(nn_Alloc *alloc, nn_component *component, ne_fs *fs, const cha
|
||||
return buf;
|
||||
}
|
||||
|
||||
size_t ne_fs_size(nn_component *component, ne_fs *fs, const char *path) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
size_t ne_fs_size(nn_address addr, const char *path) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
if(DirectoryExists(p)) return 0;
|
||||
@ -304,29 +263,29 @@ size_t ne_fs_size(nn_component *component, ne_fs *fs, const char *path) {
|
||||
return GetFileLength(p);
|
||||
}
|
||||
|
||||
size_t ne_fs_lastModified(nn_component *component, ne_fs *fs, const char *path) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
size_t ne_fs_lastModified(nn_address addr, const char *path) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
return GetFileModTime(p);
|
||||
}
|
||||
|
||||
bool ne_fs_isDirectory(nn_component *component, ne_fs *fs, const char *path) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
bool ne_fs_isDirectory(nn_address addr, const char *path) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
return DirectoryExists(p);
|
||||
}
|
||||
|
||||
bool ne_fs_makeDirectory(nn_component *component, ne_fs *fs, const char *path) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
bool ne_fs_makeDirectory(nn_address addr, const char *path) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
return MakeDirectory(p) == 0;
|
||||
}
|
||||
|
||||
bool ne_fs_exists(nn_component *component, ne_fs *fs, const char *path) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
bool ne_fs_exists(nn_address addr, const char *path) {
|
||||
const char *p = ne_fs_diskPath(addr, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
return FileExists(p) || DirectoryExists(p);
|
||||
@ -677,16 +636,14 @@ int main() {
|
||||
// 1MB of RAM, 16 components max
|
||||
nn_computer *computer = nn_newComputer(universe, "testMachine", arch, NULL, 1*1024*1024, 16);
|
||||
nn_setEnergyInfo(computer, 5000, 5000);
|
||||
nn_setCallBudget(computer, 18000);
|
||||
//nn_setCallBudget(computer, 18000);
|
||||
nn_addSupportedArchitecture(computer, arch);
|
||||
|
||||
nn_eeprom genericEEPROM = {
|
||||
.userdata = NULL,
|
||||
.refc = 1,
|
||||
nn_eepromTable genericEEPROMTable = {
|
||||
.userdata = "luaBios.lua",
|
||||
.deinit = NULL,
|
||||
.control = ne_eeprom_getControl,
|
||||
.getSize = ne_eeprom_getSize,
|
||||
.getDataSize = ne_eeprom_getDataSize,
|
||||
.size = 4096,
|
||||
.dataSize = 1024,
|
||||
.getLabel = ne_eeprom_getLabel,
|
||||
.setLabel = ne_eeprom_setLabel,
|
||||
.get = ne_eeprom_get,
|
||||
@ -697,22 +654,18 @@ int main() {
|
||||
.makeReadonly = ne_eeprom_makeReadonly,
|
||||
};
|
||||
|
||||
nn_addEeprom(computer, "luaBios.lua", 0, &genericEEPROM);
|
||||
nn_eeprom *genericEEPROM = nn_newEEPROM(&ctx, genericEEPROMTable, ne_eeprom_ctrl);
|
||||
|
||||
ne_fs fs = {
|
||||
.files = {NULL},
|
||||
.fileLen = 0,
|
||||
};
|
||||
nn_addEeprom(computer, "luaBios.lua", 0, genericEEPROM);
|
||||
|
||||
nn_filesystem genericFS = {
|
||||
.refc = 0,
|
||||
.userdata = &fs,
|
||||
nn_address fsFolder = "OpenOS";
|
||||
nn_filesystemTable genericFSTable = {
|
||||
.userdata = fsFolder,
|
||||
.deinit = NULL,
|
||||
.control = (void *)ne_fs_getControl,
|
||||
.getLabel = ne_eeprom_getLabel,
|
||||
.setLabel = ne_eeprom_setLabel,
|
||||
.spaceUsed = ne_fs_spaceUsed,
|
||||
.spaceTotal = ne_fs_spaceTotal,
|
||||
.spaceTotal = 1*1024*1024,
|
||||
.isReadOnly = ne_eeprom_isReadonly,
|
||||
.size = (void *)ne_fs_size,
|
||||
.remove = NULL,
|
||||
@ -728,7 +681,8 @@ int main() {
|
||||
.read = (void *)ne_fs_read,
|
||||
.seek = (void *)ne_fs_seek,
|
||||
};
|
||||
nn_addFileSystem(computer, "OpenOS", 1, &genericFS);
|
||||
nn_filesystem *genericFS = nn_newFilesystem(&ctx, genericFSTable, ne_fs_ctrl);
|
||||
nn_addFileSystem(computer, fsFolder, 1, genericFS);
|
||||
|
||||
ne_drive drive = {
|
||||
.file = fopen("data/drive.img", "r+")
|
||||
@ -740,8 +694,8 @@ int main() {
|
||||
.userdata = &drive,
|
||||
.deinit = (void *)ne_drive_close,
|
||||
.control = (void *)ne_drive_getControl,
|
||||
.getLabel = ne_eeprom_getLabel,
|
||||
.setLabel = ne_eeprom_setLabel,
|
||||
.getLabel = ne_fs_getLabel,
|
||||
.setLabel = ne_fs_setLabel,
|
||||
.getPlatterCount = (void *)ne_drive_getPlatterCount,
|
||||
.getSectorSize = (void *)ne_drive_getSectorSize,
|
||||
.getCapacity = (void *)ne_drive_getCapacity,
|
||||
|
@ -582,25 +582,29 @@ typedef struct nn_eepromControl {
|
||||
double bytesWrittenPerTick;
|
||||
} nn_eepromControl;
|
||||
|
||||
typedef struct nn_eeprom {
|
||||
nn_refc refc;
|
||||
typedef struct nn_eepromTable {
|
||||
void *userdata;
|
||||
void (*deinit)(nn_component *component, void *userdata);
|
||||
|
||||
nn_eepromControl (*control)(nn_component *component, void *userdata);
|
||||
void (*deinit)(void *userdata);
|
||||
|
||||
// methods
|
||||
nn_size_t (*getSize)(nn_component *component, void *userdata);
|
||||
nn_size_t (*getDataSize)(nn_component *component, void *userdata);
|
||||
void (*getLabel)(nn_component *component, void *userdata, char *buf, nn_size_t *buflen);
|
||||
nn_size_t (*setLabel)(nn_component *component, void *userdata, const char *buf, nn_size_t buflen);
|
||||
nn_size_t (*get)(nn_component *component, void *userdata, char *buf);
|
||||
void (*set)(nn_component *component, void *userdata, const char *buf, nn_size_t len);
|
||||
int (*getData)(nn_component *component, void *userdata, char *buf);
|
||||
void (*setData)(nn_component *component, void *userdata, const char *buf, nn_size_t len);
|
||||
nn_bool_t (*isReadonly)(nn_component *component, void *userdata);
|
||||
void (*makeReadonly)(nn_component *component, void *userdata);
|
||||
} nn_eeprom;
|
||||
nn_size_t size;
|
||||
nn_size_t dataSize;
|
||||
void (*getLabel)(void *userdata, char *buf, nn_size_t *buflen);
|
||||
nn_size_t (*setLabel)(void *userdata, const char *buf, nn_size_t buflen);
|
||||
nn_size_t (*get)(void *userdata, char *buf);
|
||||
void (*set)(void *userdata, const char *buf, nn_size_t len);
|
||||
int (*getData)(void *userdata, char *buf);
|
||||
void (*setData)(void *userdata, const char *buf, nn_size_t len);
|
||||
nn_bool_t (*isReadonly)(void *userdata);
|
||||
void (*makeReadonly)(void *userdata);
|
||||
} nn_eepromTable;
|
||||
|
||||
typedef struct nn_eeprom nn_eeprom;
|
||||
|
||||
nn_eeprom *nn_newEEPROM(nn_Context *context, nn_eepromTable table, nn_eepromControl control);
|
||||
nn_guard *nn_getEEPROMLock(nn_eeprom *eeprom);
|
||||
void nn_retainEEPROM(nn_eeprom *eeprom);
|
||||
nn_bool_t nn_destroyEEPROM(nn_eeprom *eeprom);
|
||||
nn_component *nn_addEeprom(nn_computer *computer, nn_address address, int slot, nn_eeprom *eeprom);
|
||||
|
||||
// FileSystem
|
||||
@ -621,47 +625,51 @@ typedef struct nn_filesystemControl {
|
||||
double createEnergy;
|
||||
} nn_filesystemControl;
|
||||
|
||||
typedef struct nn_filesystem {
|
||||
nn_refc refc;
|
||||
typedef struct nn_filesystemTable {
|
||||
void *userdata;
|
||||
void (*deinit)(nn_component *component, void *userdata);
|
||||
void (*deinit)(void *userdata);
|
||||
|
||||
nn_filesystemControl (*control)(nn_component *component, void *userdata);
|
||||
void (*getLabel)(nn_component *component, void *userdata, char *buf, nn_size_t *buflen);
|
||||
nn_size_t (*setLabel)(nn_component *component, void *userdata, const char *buf, nn_size_t buflen);
|
||||
nn_filesystemControl (*control)(void *userdata);
|
||||
void (*getLabel)(void *userdata, char *buf, nn_size_t *buflen);
|
||||
nn_size_t (*setLabel)(void *userdata, const char *buf, nn_size_t buflen);
|
||||
|
||||
nn_size_t (*spaceUsed)(nn_component *component, void *userdata);
|
||||
nn_size_t (*spaceTotal)(nn_component *component, void *userdata);
|
||||
nn_bool_t (*isReadOnly)(nn_component *component, void *userdata);
|
||||
nn_size_t (*spaceUsed)(void *userdata);
|
||||
nn_size_t spaceTotal;
|
||||
nn_bool_t (*isReadOnly)(void *userdata);
|
||||
|
||||
// general operations
|
||||
nn_size_t (*size)(nn_component *component, void *userdata, const char *path);
|
||||
nn_bool_t (*remove)(nn_component *component, void *userdata, const char *path);
|
||||
nn_size_t (*lastModified)(nn_component *component, void *userdata, const char *path);
|
||||
nn_size_t (*rename)(nn_component *component, void *userdata, const char *from, const char *to);
|
||||
nn_bool_t (*exists)(nn_component *component, void *userdata, const char *path);
|
||||
nn_size_t (*size)(void *userdata, const char *path);
|
||||
nn_size_t (*remove)(void *userdata, const char *path);
|
||||
nn_size_t (*lastModified)(void *userdata, const char *path);
|
||||
nn_size_t (*rename)(void *userdata, const char *from, const char *to);
|
||||
nn_bool_t (*exists)(void *userdata, const char *path);
|
||||
|
||||
// directory operations
|
||||
nn_bool_t (*isDirectory)(nn_component *component, void *userdata, const char *path);
|
||||
nn_bool_t (*makeDirectory)(nn_component *component, void *userdata, const char *path);
|
||||
nn_bool_t (*isDirectory)(void *userdata, const char *path);
|
||||
nn_bool_t (*makeDirectory)(void *userdata, const char *path);
|
||||
// The returned array should be allocated with the supplied allocator.
|
||||
// The strings should be null terminated. Use nn_strdup for the allocation to guarantee nn_deallocStr deallocates it correctly.
|
||||
// For the array, the *exact* size of the allocation should be sizeof(char *) * (*len),
|
||||
// If it is not, the behavior is undefined.
|
||||
// We recommend first computing len then allocating, though if that is not doable or practical,
|
||||
// consider nn_resize()ing it to the correct size to guarantee a correct deallocation.
|
||||
char **(*list)(nn_Alloc *alloc, nn_component *component, void *userdata, const char *path, nn_size_t *len);
|
||||
char **(*list)(nn_Alloc *alloc, void *userdata, const char *path, nn_size_t *len);
|
||||
|
||||
// file operations
|
||||
nn_size_t (*open)(nn_component *component, void *userdata, const char *path, const char *mode);
|
||||
nn_bool_t (*close)(nn_component *component, void *userdata, int fd);
|
||||
nn_bool_t (*write)(nn_component *component, void *userdata, int fd, const char *buf, nn_size_t len);
|
||||
nn_size_t (*read)(nn_component *component, void *userdata, int fd, char *buf, nn_size_t required);
|
||||
// moved is an out pointer that says how many bytes the pointer moved.
|
||||
nn_size_t (*seek)(nn_component *component, void *userdata, int fd, const char *whence, int off, int *moved);
|
||||
} nn_filesystem;
|
||||
void *(*open)(void *userdata, const char *path, const char *mode);
|
||||
nn_bool_t (*close)(void *userdata, void *fd);
|
||||
nn_bool_t (*write)(void *userdata, void *fd, const char *buf, nn_size_t len);
|
||||
nn_size_t (*read)(void *userdata, void *fd, char *buf, nn_size_t required);
|
||||
nn_size_t (*seek)(void *userdata, void *fd, const char *whence, int off);
|
||||
} nn_filesystemTable;
|
||||
|
||||
typedef struct nn_filesystem nn_filesystem;
|
||||
|
||||
nn_filesystem *nn_newFilesystem(nn_Context *context, nn_filesystemTable table, nn_filesystemControl control);
|
||||
nn_guard *nn_getFilesystemLock(nn_filesystem *fs);
|
||||
void nn_retainFilesystem(nn_filesystem *fs);
|
||||
nn_bool_t nn_destroyFilesystem(nn_filesystem *fs);
|
||||
|
||||
nn_filesystem *nn_volatileFileSystem(nn_size_t capacity, nn_filesystemControl *control);
|
||||
nn_component *nn_addFileSystem(nn_computer *computer, nn_address address, int slot, nn_filesystem *filesystem);
|
||||
|
||||
// Drive
|
||||
|
@ -673,7 +673,11 @@ testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) {
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "archPtr");
|
||||
s->L = L;
|
||||
testLuaArch_loadEnv(L);
|
||||
assert(luaL_loadbufferx(L, testLuaSandbox, strlen(testLuaSandbox), "=machine.lua", "t") == LUA_OK);
|
||||
if(luaL_loadbufferx(L, testLuaSandbox, strlen(testLuaSandbox), "=machine.lua", "t") != LUA_OK) {
|
||||
lua_close(L);
|
||||
nn_dealloc(alloc, s, sizeof(testLuaArch));
|
||||
return NULL;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -703,7 +707,7 @@ void testLuaArch_tick(nn_computer *computer, testLuaArch *arch, void *_) {
|
||||
} else {
|
||||
const char *s = lua_tostring(arch->L, -1);
|
||||
nn_setError(computer, s);
|
||||
lua_pop(arch->L, 1);
|
||||
lua_pop(arch->L, ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user