From f61c4e3d01bacfee1e73b075f5acbc5cc963a314 Mon Sep 17 00:00:00 2001 From: IonutParau Date: Thu, 22 May 2025 13:14:19 +0200 Subject: [PATCH] basic universe implementation --- build.zig | 1 + src/neonucleus.h | 123 ++++++++++++++++++++++++++--------------------- src/universe.c | 46 ++++++++++++++++++ src/universe.h | 8 +++ src/utils.c | 29 +++++++++++ 5 files changed, 152 insertions(+), 55 deletions(-) create mode 100644 src/universe.h create mode 100644 src/utils.c diff --git a/build.zig b/build.zig index 790e8ec..6817106 100644 --- a/build.zig +++ b/build.zig @@ -5,6 +5,7 @@ fn addEngineSources(c: *std.Build.Step.Compile) void { c.addCSourceFiles(.{ .files = &[_][]const u8{ + "src/utils.c", "src/universe.c", }, }); diff --git a/src/neonucleus.h b/src/neonucleus.h index 59405e6..64927ec 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -10,14 +10,16 @@ // Magic limits // If your component needs more than these, redesign your API. -#define NN_MAX_ARGS 256 -#define NN_MAX_RETS 256 -#define NN_MAX_METHODS 256 -#define NN_MAX_USERS 256 +#define NN_MAX_ARGS 32 +#define NN_MAX_RETS 32 +#define NN_MAX_METHODS 128 +#define NN_MAX_USERS 128 #define NN_MAX_ARCHITECTURES 16 +#define NN_MAX_SIGNALS 128 +#define NN_MAX_SIGNAL_VALS 63 +#define NN_MAX_USERDATA 1024 -// Utilities, both internal and external - +typedef struct nn_guard nn_guard; typedef struct nn_universe nn_universe; typedef struct nn_computer nn_computer; typedef struct nn_component nn_component; @@ -32,15 +34,71 @@ typedef struct nn_architecture { } nn_architecture; typedef const char *nn_address; -// we expose the allocator because of addresses +// Values for architectures + +#define NN_VALUE_INT 0 +#define NN_VALUE_NUMBER 1 +#define NN_VALUE_BOOL 2 +#define NN_VALUE_CSTR 3 +#define NN_VALUE_STR 4 +#define NN_VALUE_ARRAY 5 +#define NN_VALUE_TABLE 6 +#define NN_VALUE_NIL 7 + +typedef struct nn_string { + const char *data; + size_t len; + size_t refc; +} nn_string; + +typedef struct nn_array { + struct nn_value *values; + size_t len; + size_t refc; +} nn_array; + +typedef struct nn_object { + struct nn_pair *pairs; + size_t len; + size_t refc; +} nn_table; + +typedef struct nn_value { + size_t tag; + union { + intptr_t integer; + double number; + bool boolean; + const char *cstring; + nn_string *string; + nn_array *array; + nn_table *table; + }; +} nn_value; + +typedef struct nn_pair { + nn_value key; + nn_value val; +} nn_pair; + +// we expose the allocator because of some utilities void *nn_malloc(size_t size); void *nn_realloc(void *memory, size_t newSize); void nn_free(void *memory); -nn_address nn_copyAddress(nn_address address); +// Utilities, both internal and external +char *nn_strdup(const char *s); +void *nn_memdup(const void *buf, size_t len); + +nn_guard *nn_newGuard(); +void nn_lock(nn_guard *lock); +void nn_unlock(nn_guard *lock); +void nn_deleteGuard(nn_guard *lock); nn_universe *nn_newUniverse(); void nn_unsafeDeleteUniverse(nn_universe *universe); +void *nn_queryUserdata(nn_universe *universe, const char *name); +void nn_storeUserdata(nn_universe *universe, const char *name, void *data); nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, size_t memoryLimit); void nn_tickComputer(nn_computer *computer); @@ -54,7 +112,7 @@ nn_architecture *nn_getArchitecture(nn_computer *computer); nn_architecture *nn_getNextArchitecture(nn_computer *computer); void nn_setNextArchitecture(nn_computer *computer, nn_architecture *arch); void nn_deleteComputer(nn_computer *computer); -void nn_pushSignal(nn_computer *computer, struct nn_value *values, size_t len); +void nn_pushSignal(nn_computer *computer, nn_value *values, size_t len); nn_value nn_fetchSignalValue(nn_computer *computer, size_t index); void nn_popSignal(nn_computer *computer); void nn_addUser(nn_computer *computer, const char *name); @@ -148,52 +206,7 @@ nn_value nn_getReturn(nn_computer *computer, size_t idx); size_t nn_getArgumentCount(nn_computer *computer); size_t nn_getReturnCount(nn_computer *computer); -// Values for architectures - -#define NN_VALUE_INT 0 -#define NN_VALUE_NUMBER 1 -#define NN_VALUE_BOOL 2 -#define NN_VALUE_CSTR 3 -#define NN_VALUE_STR 4 -#define NN_VALUE_ARRAY 5 -#define NN_VALUE_TABLE 6 -#define NN_VALUE_NIL 7 - -typedef struct nn_string { - const char *data; - size_t len; - size_t refc; -} nn_string; - -typedef struct nn_array { - struct nn_value *values; - size_t len; - size_t refc; -} nn_array; - -typedef struct nn_object { - struct nn_pair *pairs; - size_t len; - size_t refc; -} nn_table; - -typedef struct nn_value { - size_t tag; - union { - intptr_t integer; - double number; - bool boolean; - const char *cstring; - nn_string *string; - nn_array *array; - nn_table *table; - }; -} nn_value; - -typedef struct nn_pair { - nn_value key; - nn_value val; -} nn_pair; +// Value stuff nn_value nn_values_retain(nn_value val); void nn_values_drop(nn_value val); diff --git a/src/universe.c b/src/universe.c index 5f55151..fd8ac8f 100644 --- a/src/universe.c +++ b/src/universe.c @@ -1 +1,47 @@ #include "neonucleus.h" +#include + +typedef struct nn_universe_udata { + char *name; + void *userdata; +} nn_universe_udata; + +typedef struct nn_universe { + nn_universe_udata udata[NN_MAX_USERDATA]; + size_t udataLen; +} nn_universe; + +nn_universe *nn_newUniverse() { + nn_universe *u = nn_malloc(sizeof(nn_universe)); + if(u == NULL) return u; + // we leave udata uninitialized because it does not matter + u->udataLen = 0; + return u; +} + +void nn_unsafeDeleteUniverse(nn_universe *universe) { + for(size_t i = 0; i < universe->udataLen; i++) { + nn_free(universe->udata[i].name); + } +} + +void *nn_queryUserdata(nn_universe *universe, const char *name) { + for(size_t i = 0; i < universe->udataLen; i++) { + if(strcmp(universe->udata[i].name, name) == 0) { + return universe->udata[i].userdata; + } + } + return NULL; +} + +void nn_storeUserdata(nn_universe *universe, const char *name, void *data) { + if(universe->udataLen == NN_MAX_USERDATA) return; // prevent overflow + + size_t idx = universe->udataLen; + char *allocName = nn_strdup(name); + if(allocName == NULL) return; + + universe->udata[idx].name = allocName; + universe->udata[idx].userdata = data; + universe->udataLen++; +} diff --git a/src/universe.h b/src/universe.h new file mode 100644 index 0000000..9f3eed3 --- /dev/null +++ b/src/universe.h @@ -0,0 +1,8 @@ +#ifndef NEONUCLEUS_UNIVERSE_H +#define NEONUCLEUS_UNIVERSE_H + +#include "neonucleus.h" + +typedef struct nn_universe nn_universe; + +#endif diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..a348467 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,29 @@ +#include "neonucleus.h" +#include +#include + +void *nn_malloc(size_t size) { + return malloc(size); +} + +void *nn_realloc(void *memory, size_t newSize) { + return realloc(memory, newSize); +} + +void nn_free(void *memory) { + free(memory); +} + +// Utilities, both internal and external +char *nn_strdup(const char *s) { + size_t l = strlen(s); + char *m = nn_malloc(l+1); + if(m == NULL) return m; + return strcpy(m, s); +} + +void *nn_memdup(const void *buf, size_t len) { + char *m = malloc(len); + if(m == NULL) return m; + return memcpy(m, buf, len); +}