From 361c1b29e388b1b4956ac11b50e2718855da17b2 Mon Sep 17 00:00:00 2001 From: IonutParau Date: Thu, 17 Jul 2025 21:23:38 +0200 Subject: [PATCH] reworked how methods are defined --- TODO.md | 8 ++++++ src/component.c | 54 ++++++++++++++++++++++++++++++------- src/component.h | 7 ++--- src/components/drive.c | 18 ++++++------- src/components/eeprom.c | 28 +++++++++---------- src/components/filesystem.c | 36 ++++++++++++------------- src/components/gpu.c | 38 ++++++++++++++------------ src/components/screen.c | 4 +-- src/neonucleus.h | 8 +++++- src/testLuaArch.c | 1 + 10 files changed, 128 insertions(+), 74 deletions(-) diff --git a/TODO.md b/TODO.md index 2b5d6d4..c281f09 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,11 @@ +# Code quality stuff + +- Use the same namespacing style everywhere, that being +`nn__` for functions related to "classes", +`nn_` for static functions, +`nn__t` for types. +- Rework to API to be much more future-proof to reduce potential breaking changes. + # Parity with Vanilla OC (only the stuff that makes sense for an emulator) - in-memory version of `filesystem` diff --git a/src/component.c b/src/component.c index 1746687..23825ce 100644 --- a/src/component.c +++ b/src/component.c @@ -23,33 +23,48 @@ void nn_destroyComponentTable(nn_componentTable *table) { nn_Alloc alloc = table->alloc; nn_deallocStr(&alloc, table->name); for(nn_size_t i = 0; i < table->methodCount; i++) { - nn_method method = table->methods[i]; + nn_method_t method = table->methods[i]; nn_deallocStr(&alloc, method.name); nn_deallocStr(&alloc, method.doc); } nn_dealloc(&alloc, table, sizeof(nn_componentTable)); } -void nn_defineMethod(nn_componentTable *table, const char *methodName, nn_bool_t direct, nn_componentMethod *methodFunc, void *methodUserdata, const char *methodDoc) { - if(table->methodCount == NN_MAX_METHODS) return; - nn_method method; +nn_method_t *nn_defineMethod(nn_componentTable *table, const char *methodName, nn_componentMethod *methodFunc, const char *methodDoc) { + if(table->methodCount == NN_MAX_METHODS) return NULL; + nn_method_t method; method.method = methodFunc; method.name = nn_strdup(&table->alloc, methodName); - if(method.name == NULL) return; - method.direct = direct; + if(method.name == NULL) return NULL; + method.direct = true; method.doc = nn_strdup(&table->alloc, methodDoc); if(method.doc == NULL) { nn_deallocStr(&table->alloc, method.name); - return; + return NULL; } - method.userdata = methodUserdata; + method.userdata = NULL; + method.condition = NULL; table->methods[table->methodCount] = method; + nn_method_t *ptr = table->methods + table->methodCount; table->methodCount++; + return ptr; +} + +void nn_method_setDirect(nn_method_t *method, nn_bool_t direct) { + method->direct = direct; +} + +void nn_method_setUserdata(nn_method_t *method, void *userdata) { + method->userdata = userdata; +} + +void nn_method_setCondition(nn_method_t *method, nn_componentMethodCondition_t *condition) { + method->condition = condition; } const char *nn_getTableMethod(nn_componentTable *table, nn_size_t idx, nn_bool_t *outDirect) { if(idx >= table->methodCount) return NULL; - nn_method method = table->methods[idx]; + nn_method_t method = table->methods[idx]; if(outDirect != NULL) *outDirect = method.direct; return method.name; } @@ -63,6 +78,22 @@ const char *nn_methodDoc(nn_componentTable *table, const char *methodName) { return NULL; } +static nn_bool_t nni_checkMethodEnabled(nn_method_t method, void *statePtr) { + if(method.condition == NULL) return true; + return method.condition(statePtr, method.userdata); +} + +nn_bool_t nn_isMethodEnabled(nn_component *component, const char *methodName) { + nn_componentTable *table = component->table; + for(nn_size_t i = 0; i < table->methodCount; i++) { + if(nn_strcmp(table->methods[i].name, methodName) == 0) { + nn_method_t method = table->methods[i]; + return nni_checkMethodEnabled(method, component->statePtr); + } + } + return false; +} + nn_computer *nn_getComputerOfComponent(nn_component *component) { return component->computer; } @@ -90,12 +121,15 @@ void *nn_getComponentUserdata(nn_component *component) { nn_bool_t nn_invokeComponentMethod(nn_component *component, const char *name) { nn_componentTable *table = component->table; for(nn_size_t i = 0; i < table->methodCount; i++) { - nn_method method = table->methods[i]; + nn_method_t method = table->methods[i]; if(nn_strcmp(method.name, name) == 0) { nn_callCost(component->computer, NN_CALL_COST); if(!method.direct) { nn_triggerIndirect(component->computer); } + if(!nni_checkMethodEnabled(method, component->statePtr)) { + return false; // pretend it's gone + } method.method(component->statePtr, method.userdata, component, component->computer); return true; } diff --git a/src/component.h b/src/component.h index 14b9ed4..797b477 100644 --- a/src/component.h +++ b/src/component.h @@ -4,13 +4,14 @@ #include "neonucleus.h" #include "computer.h" -typedef struct nn_method { +typedef struct nn_method_t { char *name; nn_componentMethod *method; void *userdata; char *doc; nn_bool_t direct; -} nn_method; + nn_componentMethodCondition_t *condition; +} nn_method_t; typedef struct nn_componentTable { char *name; @@ -18,7 +19,7 @@ typedef struct nn_componentTable { void *userdata; nn_componentConstructor *constructor; nn_componentDestructor *destructor; - nn_method methods[NN_MAX_METHODS]; + nn_method_t methods[NN_MAX_METHODS]; nn_size_t methodCount; } nn_componentTable; diff --git a/src/components/drive.c b/src/components/drive.c index 6a0ea8d..755cbb5 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -239,15 +239,15 @@ void nn_loadDriveTable(nn_universe *universe) { nn_componentTable *driveTable = nn_newComponentTable(nn_getAllocator(universe), "drive", NULL, NULL, (nn_componentDestructor *)nn_drive_destroy); nn_storeUserdata(universe, "NN:DRIVE", driveTable); - nn_defineMethod(driveTable, "getLabel", false, (nn_componentMethod *)nn_drive_getLabel, NULL, "getLabel():string - Get the current label of the drive."); - nn_defineMethod(driveTable, "setLabel", false, (nn_componentMethod *)nn_drive_setLabel, NULL, "setLabel(value:string):string - Sets the label of the drive. Returns the new value, which may be truncated."); - nn_defineMethod(driveTable, "getSectorSize", true, (nn_componentMethod *)nn_drive_getSectorSize, NULL, "getSectorSize():number - Returns the size of a single sector on the drive, in bytes."); - nn_defineMethod(driveTable, "getPlatterCount", true, (nn_componentMethod *)nn_drive_getPlatterCount, NULL, "getPlatterCount():number - Returns the number of platters in the drive."); - nn_defineMethod(driveTable, "getCapacity", true, (nn_componentMethod *)nn_drive_getCapacity, NULL, "getCapacity():number - Returns the total capacity of the drive, in bytes."); - nn_defineMethod(driveTable, "readSector", false, (nn_componentMethod *)nn_drive_readSector, NULL, "readSector(sector:number):string - Read the current contents of the specified sector."); - nn_defineMethod(driveTable, "writeSector", false, (nn_componentMethod *)nn_drive_writeSector, NULL, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); - nn_defineMethod(driveTable, "readByte", false, (nn_componentMethod *)nn_drive_readByte, NULL, "readByte(offset:number):number - Read a single byte at the specified offset."); - nn_defineMethod(driveTable, "writeByte", false, (nn_componentMethod *)nn_drive_writeByte, NULL, "writeByte(offset:number, value:number) - Write a single byte to the specified offset."); + nn_defineMethod(driveTable, "getLabel", (nn_componentMethod *)nn_drive_getLabel, "getLabel():string - Get the current label of the drive."); + nn_defineMethod(driveTable, "setLabel", (nn_componentMethod *)nn_drive_setLabel, "setLabel(value:string):string - Sets the label of the drive. Returns the new value, which may be truncated."); + nn_defineMethod(driveTable, "getSectorSize", (nn_componentMethod *)nn_drive_getSectorSize, "getSectorSize():number - Returns the size of a single sector on the drive, in bytes."); + nn_defineMethod(driveTable, "getPlatterCount", (nn_componentMethod *)nn_drive_getPlatterCount, "getPlatterCount():number - Returns the number of platters in the drive."); + nn_defineMethod(driveTable, "getCapacity", (nn_componentMethod *)nn_drive_getCapacity, "getCapacity():number - Returns the total capacity of the drive, in bytes."); + nn_defineMethod(driveTable, "readSector", (nn_componentMethod *)nn_drive_readSector, "readSector(sector:number):string - Read the current contents of the specified sector."); + nn_defineMethod(driveTable, "writeSector", (nn_componentMethod *)nn_drive_writeSector, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); + nn_defineMethod(driveTable, "readByte", (nn_componentMethod *)nn_drive_readByte, "readByte(offset:number):number - Read a single byte at the specified offset."); + nn_defineMethod(driveTable, "writeByte", (nn_componentMethod *)nn_drive_writeByte, "writeByte(offset:number, value:number) - Write a single byte to the specified offset."); } nn_component *nn_addDrive(nn_computer *computer, nn_address address, int slot, nn_drive *drive) { diff --git a/src/components/eeprom.c b/src/components/eeprom.c index db0a3f0..0bd92ed 100644 --- a/src/components/eeprom.c +++ b/src/components/eeprom.c @@ -367,20 +367,20 @@ void nn_loadEepromTable(nn_universe *universe) { nn_componentTable *eepromTable = nn_newComponentTable(nn_getAllocator(universe), "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", true, (void *)nn_eeprom_getLabel, NULL, "getLabel(): string - Returns the current label."); - nn_defineMethod(eepromTable, "setLabel", true, (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", true, (void *)nn_eeprom_get, NULL, "get(): string - Reads the current code contents."); - nn_defineMethod(eepromTable, "set", true, (void *)nn_eeprom_set, NULL, "set(data: string) - Sets the current code contents."); - nn_defineMethod(eepromTable, "getData", true, (void *)nn_eeprom_getData, NULL, "getData(): string - Reads the current data contents."); - nn_defineMethod(eepromTable, "setData", true, (void *)nn_eeprom_setData, NULL, "setData(data: string) - Sets the current data contents."); - nn_defineMethod(eepromTable, "getArchitecture", true, (void *)nn_eeprom_getArchitecture, NULL, "getArchitecture(): string - Gets the intended architecture."); - nn_defineMethod(eepromTable, "setArchitecture", true, (void *)nn_eeprom_setArchitecture, NULL, "setArchitecture(data: string) - Sets the intended architecture."); - nn_defineMethod(eepromTable, "isReadOnly", true, (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", true, (void *)nn_eeprom_getChecksum, NULL, "getChecksum(): string - Returns a checksum of the data on the EEPROM."); + nn_defineMethod(eepromTable, "getSize", (void *)nn_eeprom_getSize, "getSize(): integer - Returns the maximum code capacity of the EEPROM."); + nn_defineMethod(eepromTable, "getDataSize", (void *)nn_eeprom_getDataSize, "getDataSize(): integer - Returns the maximum data capacity of the EEPROM."); + nn_defineMethod(eepromTable, "getLabel", (void *)nn_eeprom_getLabel, "getLabel(): string - Returns the current label."); + nn_defineMethod(eepromTable, "setLabel", (void *)nn_eeprom_setLabel, "setLabel(label: string): string - Sets the new label. Returns the actual label set to, which may be truncated."); + nn_defineMethod(eepromTable, "get", (void *)nn_eeprom_get, "get(): string - Reads the current code contents."); + nn_defineMethod(eepromTable, "set", (void *)nn_eeprom_set, "set(data: string) - Sets the current code contents."); + nn_defineMethod(eepromTable, "getData", (void *)nn_eeprom_getData, "getData(): string - Reads the current data contents."); + nn_defineMethod(eepromTable, "setData", (void *)nn_eeprom_setData, "setData(data: string) - Sets the current data contents."); + nn_defineMethod(eepromTable, "getArchitecture", (void *)nn_eeprom_getArchitecture, "getArchitecture(): string - Gets the intended architecture."); + nn_defineMethod(eepromTable, "setArchitecture", (void *)nn_eeprom_setArchitecture, "setArchitecture(data: string) - Sets the intended architecture."); + nn_defineMethod(eepromTable, "isReadOnly", (void *)nn_eeprom_isReadOnly, "isReadOnly(): boolean - Returns whether this EEPROM is read-only."); + nn_defineMethod(eepromTable, "makeReadOnly", (void *)nn_eeprom_makeReadonly, "makeReadOnly() - Makes the current EEPROM read-only. Normally, this cannot be undone."); + nn_defineMethod(eepromTable, "makeReadonly", (void *)nn_eeprom_makeReadonly, "makeReadonly() - Legacy alias to makeReadOnly()"); + nn_defineMethod(eepromTable, "getChecksum", (void *)nn_eeprom_getChecksum, "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) { diff --git a/src/components/filesystem.c b/src/components/filesystem.c index 6f73d6d..af2f790 100644 --- a/src/components/filesystem.c +++ b/src/components/filesystem.c @@ -649,24 +649,24 @@ void nn_loadFilesystemTable(nn_universe *universe) { nn_componentTable *fsTable = nn_newComponentTable(nn_getAllocator(universe), "filesystem", NULL, NULL, (nn_componentDestructor *)nn_fs_destroy); nn_storeUserdata(universe, "NN:FILESYSTEM", fsTable); - nn_defineMethod(fsTable, "getLabel", true, (nn_componentMethod *)nn_fs_getLabel, NULL, "getLabel(): string - Returns the label of the filesystem."); - nn_defineMethod(fsTable, "setLabel", true, (nn_componentMethod *)nn_fs_setLabel, NULL, "setLabel(label: string): string - Sets a new label for the filesystem and returns the new label of the filesystem, which may have been truncated."); - nn_defineMethod(fsTable, "spaceUsed", true, (nn_componentMethod *)nn_fs_spaceUsed, NULL, "spaceUsed(): integer - Returns the amounts of bytes used."); - nn_defineMethod(fsTable, "spaceTotal", true, (nn_componentMethod *)nn_fs_spaceTotal, NULL, "spaceTotal(): integer - Returns the capacity of the filesystem."); - nn_defineMethod(fsTable, "isReadOnly", true, (nn_componentMethod *)nn_fs_isReadOnly, NULL, "isReadOnly(): boolean - Returns whether the filesystem is in read-only mode."); - nn_defineMethod(fsTable, "size", true, (nn_componentMethod *)nn_fs_size, NULL, "size(path: string): integer - Gets the size, in bytes, of a file."); - nn_defineMethod(fsTable, "remove", true, (nn_componentMethod *)nn_fs_remove, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); - nn_defineMethod(fsTable, "lastModified", true, (nn_componentMethod *)nn_fs_lastModified, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); - nn_defineMethod(fsTable, "rename", true, (nn_componentMethod *)nn_fs_rename, NULL, "rename(from: string, to: string): boolean - Moves files from one path to another."); - nn_defineMethod(fsTable, "exists", true, (nn_componentMethod *)nn_fs_exists, NULL, "exists(path: string): boolean - Checks whether a file exists."); - nn_defineMethod(fsTable, "isDirectory", true, (nn_componentMethod *)nn_fs_isDirectory, NULL, "isDirectory(path: string): boolean - Returns whether a file is actually a directory."); - nn_defineMethod(fsTable, "makeDirectory", true, (nn_componentMethod *)nn_fs_makeDirectory, NULL, "makeDirectory(path: string): boolean - Creates a new directory at the given path. Returns whether it succeeded."); - nn_defineMethod(fsTable, "list", true, (nn_componentMethod *)nn_fs_list, NULL, "list(path: string): string[] - Returns a list of file paths. Directories will have a / after them"); - nn_defineMethod(fsTable, "open", true, (nn_componentMethod *)nn_fs_open, NULL, "open(path: string[, mode: string = \"r\"]): integer - Opens a file, may create it."); - nn_defineMethod(fsTable, "close", true, (nn_componentMethod *)nn_fs_close, NULL, "close(fd: integer): boolean - Closes a file."); - nn_defineMethod(fsTable, "write", true, (nn_componentMethod *)nn_fs_write, NULL, "write(fd: integer, data: string): boolean - Writes data to a file."); - nn_defineMethod(fsTable, "read", true, (nn_componentMethod *)nn_fs_read, NULL, "read(fd: integer, len: number): string - Reads bytes from a file. Infinity is a valid length, in which case it reads as much as possible."); - nn_defineMethod(fsTable, "seek", true, (nn_componentMethod *)nn_fs_seek, NULL, "seek(fd: integer, whence: string, offset: integer): integer - Seeks a file. Returns the new position. Valid whences are set, cur and end."); + nn_defineMethod(fsTable, "getLabel", (nn_componentMethod *)nn_fs_getLabel, "getLabel(): string - Returns the label of the filesystem."); + nn_defineMethod(fsTable, "setLabel", (nn_componentMethod *)nn_fs_setLabel, "setLabel(label: string): string - Sets a new label for the filesystem and returns the new label of the filesystem, which may have been truncated."); + nn_defineMethod(fsTable, "spaceUsed", (nn_componentMethod *)nn_fs_spaceUsed, "spaceUsed(): integer - Returns the amounts of bytes used."); + nn_defineMethod(fsTable, "spaceTotal", (nn_componentMethod *)nn_fs_spaceTotal, "spaceTotal(): integer - Returns the capacity of the filesystem."); + nn_defineMethod(fsTable, "isReadOnly", (nn_componentMethod *)nn_fs_isReadOnly, "isReadOnly(): boolean - Returns whether the filesystem is in read-only mode."); + nn_defineMethod(fsTable, "size", (nn_componentMethod *)nn_fs_size, "size(path: string): integer - Gets the size, in bytes, of a file."); + nn_defineMethod(fsTable, "remove", (nn_componentMethod *)nn_fs_remove, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); + nn_defineMethod(fsTable, "lastModified", (nn_componentMethod *)nn_fs_lastModified, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); + nn_defineMethod(fsTable, "rename", (nn_componentMethod *)nn_fs_rename, "rename(from: string, to: string): boolean - Moves files from one path to another."); + nn_defineMethod(fsTable, "exists", (nn_componentMethod *)nn_fs_exists, "exists(path: string): boolean - Checks whether a file exists."); + nn_defineMethod(fsTable, "isDirectory", (nn_componentMethod *)nn_fs_isDirectory, "isDirectory(path: string): boolean - Returns whether a file is actually a directory."); + nn_defineMethod(fsTable, "makeDirectory", (nn_componentMethod *)nn_fs_makeDirectory, "makeDirectory(path: string): boolean - Creates a new directory at the given path. Returns whether it succeeded."); + nn_defineMethod(fsTable, "list", (nn_componentMethod *)nn_fs_list, "list(path: string): string[] - Returns a list of file paths. Directories will have a / after them"); + nn_defineMethod(fsTable, "open", (nn_componentMethod *)nn_fs_open, "open(path: string[, mode: string = \"r\"]): integer - Opens a file, may create it."); + nn_defineMethod(fsTable, "close", (nn_componentMethod *)nn_fs_close, "close(fd: integer): boolean - Closes a file."); + nn_defineMethod(fsTable, "write", (nn_componentMethod *)nn_fs_write, "write(fd: integer, data: string): boolean - Writes data to a file."); + nn_defineMethod(fsTable, "read", (nn_componentMethod *)nn_fs_read, "read(fd: integer, len: number): string - Reads bytes from a file. Infinity is a valid length, in which case it reads as much as possible."); + nn_defineMethod(fsTable, "seek", (nn_componentMethod *)nn_fs_seek, "seek(fd: integer, whence: string, offset: integer): integer - Seeks a file. Returns the new position. Valid whences are set, cur and end."); } nn_component *nn_addFileSystem(nn_computer *computer, nn_address address, int slot, nn_filesystem *filesystem) { diff --git a/src/components/gpu.c b/src/components/gpu.c index 76d4fcd..02d7609 100644 --- a/src/components/gpu.c +++ b/src/components/gpu.c @@ -435,23 +435,27 @@ void nn_loadGraphicsCardTable(nn_universe *universe) { nn_componentTable *gpuTable = nn_newComponentTable(nn_getAllocator(universe), "gpu", NULL, NULL, (nn_componentDestructor *)nni_gpuDeinit); nn_storeUserdata(universe, "NN:GPU", gpuTable); - nn_defineMethod(gpuTable, "bind", false, (nn_componentMethod *)nni_gpu_bind, NULL, "bind(addr: string[, reset: boolean = false]): boolean - Bind a GPU to a screen. Very expensive. If reset is true, it will clear the screen."); - nn_defineMethod(gpuTable, "getScreen", true, (nn_componentMethod *)nni_gpu_getScreen, NULL, "getScreen(): string"); - nn_defineMethod(gpuTable, "set", true, (nn_componentMethod *)nni_gpu_set, NULL, "set(x: integer, y: integer, text: string[, vertical: boolean = false]) - Modifies the screen at a specific x or y. If vertical is false, it will display it horizontally. If it is true, it will display it vertically."); - nn_defineMethod(gpuTable, "get", true, (nn_componentMethod *)nni_gpu_get, NULL, "get(x: integer, y: integer): string, integer, integer, integer?, integer? - Returns the character, foreground color, background color, foreground palette index (if applicable), background palette index (if applicable) of a pixel"); - nn_defineMethod(gpuTable, "maxResolution", true, (nn_componentMethod *)nni_gpu_maxResolution, NULL, "maxResolution(): integer, integer - Gets the maximum resolution supported by the bound screen."); - nn_defineMethod(gpuTable, "getResolution", true, (nn_componentMethod *)nni_gpu_getResolution, NULL, "getResolution(): integer, integer - Gets the current resolution of the bound screen."); - nn_defineMethod(gpuTable, "setResolution", true, (nn_componentMethod *)nni_gpu_setResolution, NULL, "maxResolution(): integer, integer - Changes the resolution of the bound screen."); - nn_defineMethod(gpuTable, "setBackground", true, (nn_componentMethod *)nni_gpu_setBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "setForeground", true, (nn_componentMethod *)nni_gpu_setForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getBackground", true, (nn_componentMethod *)nni_gpu_getBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getForeground", true, (nn_componentMethod *)nni_gpu_getForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getDepth", true, (nn_componentMethod *)nni_gpu_getDepth, NULL, "getDepth(): number - The currently set color depth of the screen, in bits. Can be 1, 4 or 8."); - nn_defineMethod(gpuTable, "setDepth", true, (nn_componentMethod *)nni_gpu_setDepth, NULL, "setDepth(depth: integer): string - Changes the screen depth. Valid values can be 1, 4, 8, 16 or 24, however check maxDepth for the maximum supported value of the screen. Using a depth higher than what is supported by the screen will error. Returns the name of the new depth."); - nn_defineMethod(gpuTable, "maxDepth", true, (nn_componentMethod *)nni_gpu_maxDepth, NULL, "maxDepth(): number - The maximum supported depth of the screen."); - nn_defineMethod(gpuTable, "fill", true, (nn_componentMethod *)nni_gpu_fill, NULL, "fill(x: integer, y: integer, w: integer, h: integer, s: string)"); - nn_defineMethod(gpuTable, "copy", true, (nn_componentMethod *)nni_gpu_copy, NULL, "copy(x: integer, y: integer, w: integer, h: integer, tx: integer, ty: integer) - Copies stuff"); - nn_defineMethod(gpuTable, "getViewport", true, (nn_componentMethod *)nni_gpu_getViewport, NULL, "getViewport(): integer, integer - Gets the current viewport resolution"); + nn_method_t *method = NULL; + + method = nn_defineMethod(gpuTable, "bind", (nn_componentMethod *)nni_gpu_bind, "bind(addr: string[, reset: boolean = false]): boolean - Bind a GPU to a screen. Very expensive. If reset is true, it will clear the screen."); + nn_method_setDirect(method, false); + + nn_defineMethod(gpuTable, "getScreen", (nn_componentMethod *)nni_gpu_getScreen, "getScreen(): string"); + nn_defineMethod(gpuTable, "set", (nn_componentMethod *)nni_gpu_set, "set(x: integer, y: integer, text: string[, vertical: boolean = false]) - Modifies the screen at a specific x or y. If vertical is false, it will display it horizontally. If it is true, it will display it vertically."); + nn_defineMethod(gpuTable, "get", (nn_componentMethod *)nni_gpu_get, "get(x: integer, y: integer): string, integer, integer, integer?, integer? - Returns the character, foreground color, background color, foreground palette index (if applicable), background palette index (if applicable) of a pixel"); + nn_defineMethod(gpuTable, "maxResolution", (nn_componentMethod *)nni_gpu_maxResolution, "maxResolution(): integer, integer - Gets the maximum resolution supported by the bound screen."); + nn_defineMethod(gpuTable, "getResolution", (nn_componentMethod *)nni_gpu_getResolution, "getResolution(): integer, integer - Gets the current resolution of the bound screen."); + nn_defineMethod(gpuTable, "setResolution", (nn_componentMethod *)nni_gpu_setResolution, "maxResolution(): integer, integer - Changes the resolution of the bound screen."); + nn_defineMethod(gpuTable, "setBackground", (nn_componentMethod *)nni_gpu_setBackground, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "setForeground", (nn_componentMethod *)nni_gpu_setForeground, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getBackground", (nn_componentMethod *)nni_gpu_getBackground, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getForeground", (nn_componentMethod *)nni_gpu_getForeground, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getDepth", (nn_componentMethod *)nni_gpu_getDepth, "getDepth(): number - The currently set color depth of the screen, in bits. Can be 1, 4 or 8."); + nn_defineMethod(gpuTable, "setDepth", (nn_componentMethod *)nni_gpu_setDepth, "setDepth(depth: integer): string - Changes the screen depth. Valid values can be 1, 4, 8, 16 or 24, however check maxDepth for the maximum supported value of the screen. Using a depth higher than what is supported by the screen will error. Returns the name of the new depth."); + nn_defineMethod(gpuTable, "maxDepth", (nn_componentMethod *)nni_gpu_maxDepth, "maxDepth(): number - The maximum supported depth of the screen."); + nn_defineMethod(gpuTable, "fill", (nn_componentMethod *)nni_gpu_fill, "fill(x: integer, y: integer, w: integer, h: integer, s: string)"); + nn_defineMethod(gpuTable, "copy", (nn_componentMethod *)nni_gpu_copy, "copy(x: integer, y: integer, w: integer, h: integer, tx: integer, ty: integer) - Copies stuff"); + nn_defineMethod(gpuTable, "getViewport", (nn_componentMethod *)nni_gpu_getViewport, "getViewport(): integer, integer - Gets the current viewport resolution"); } nn_component *nn_addGPU(nn_computer *computer, nn_address address, int slot, nn_gpuControl *control) { diff --git a/src/components/screen.c b/src/components/screen.c index 4ac668c..5907567 100644 --- a/src/components/screen.c +++ b/src/components/screen.c @@ -240,8 +240,8 @@ void nn_loadScreenTable(nn_universe *universe) { nn_componentTable *screenTable = nn_newComponentTable(nn_getAllocator(universe), "screen", NULL, NULL, (nn_componentDestructor *)nn_screenComp_destroy); nn_storeUserdata(universe, "NN:SCREEN", screenTable); - nn_defineMethod(screenTable, "getKeyboards", true, (nn_componentMethod *)nn_screenComp_getKeyboards, NULL, "getKeyboards(): string[] - Returns the keyboards registered to this screen."); - nn_defineMethod(screenTable, "getAspectRatio", true, (nn_componentMethod *)nn_screenComp_getAspectRatio, NULL, ""); + nn_defineMethod(screenTable, "getKeyboards", (nn_componentMethod *)nn_screenComp_getKeyboards, "getKeyboards(): string[] - Returns the keyboards registered to this screen."); + nn_defineMethod(screenTable, "getAspectRatio", (nn_componentMethod *)nn_screenComp_getAspectRatio, ""); } nn_componentTable *nn_getScreenTable(nn_universe *universe) { diff --git a/src/neonucleus.h b/src/neonucleus.h index 2798830..99679bc 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -527,12 +527,18 @@ nn_component *nn_iterComponent(nn_computer *computer, nn_size_t *internalIndex); 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); +typedef nn_bool_t nn_componentMethodCondition_t(void *componentUserdata, void *methodUserdata); +typedef struct nn_method_t nn_method_t; nn_componentTable *nn_newComponentTable(nn_Alloc *alloc, const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor); void nn_destroyComponentTable(nn_componentTable *table); -void nn_defineMethod(nn_componentTable *table, const char *methodName, nn_bool_t direct, nn_componentMethod *methodFunc, void *methodUserdata, const char *methodDoc); +nn_method_t *nn_defineMethod(nn_componentTable *table, const char *methodName, nn_componentMethod *methodFunc, const char *methodDoc); +void nn_method_setDirect(nn_method_t *method, nn_bool_t direct); +void nn_method_setUserdata(nn_method_t *method, void *userdata); +void nn_method_setCondition(nn_method_t *method, nn_componentMethodCondition_t *condition); const char *nn_getTableMethod(nn_componentTable *table, nn_size_t idx, nn_bool_t *outDirect); const char *nn_methodDoc(nn_componentTable *table, const char *methodName); +nn_bool_t nn_isMethodEnabled(nn_component *component, const char *methodName); // Component calling diff --git a/src/testLuaArch.c b/src/testLuaArch.c index a7e543e..dce41d6 100644 --- a/src/testLuaArch.c +++ b/src/testLuaArch.c @@ -399,6 +399,7 @@ static int testLuaArch_component_methods(lua_State *L) { const char *name = nn_getTableMethod(table, i, &direct); if(name == NULL) break; i++; + if(!nn_isMethodEnabled(component, name)) continue; lua_pushboolean(L, direct); lua_setfield(L, methods, name); }