mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
more work on the rewrite
This commit is contained in:
parent
fa84ac936f
commit
ab22feec69
@ -211,13 +211,13 @@ const char *nn_getComputerAddress(nn_Computer *computer);
|
|||||||
// Everything is limited by the architecture.
|
// Everything is limited by the architecture.
|
||||||
void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
||||||
// Gets the current architecture.
|
// Gets the current architecture.
|
||||||
nn_Architecture *nn_getArchitecture(nn_Computer *computer);
|
const nn_Architecture *nn_getArchitecture(nn_Computer *computer);
|
||||||
// Sets the computer's desired architecture.
|
// Sets the computer's desired architecture.
|
||||||
// The desired architecture indicates, when the computer state is CHARCH, what the new architecture should be.
|
// The desired architecture indicates, when the computer state is CHARCH, what the new architecture should be.
|
||||||
// This is set even if it is not in the supported architecture list, *you must check if it is in that list first.*
|
// This is set even if it is not in the supported architecture list, *you must check if it is in that list first.*
|
||||||
void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
||||||
// Gets the desired architecture. This is the architecture the computer should use after changing architectures.
|
// Gets the desired architecture. This is the architecture the computer should use after changing architectures.
|
||||||
nn_Architecture *nn_getDesiredArchitecture(nn_Computer *computer);
|
const nn_Architecture *nn_getDesiredArchitecture(nn_Computer *computer);
|
||||||
// Adds a new supported architecture, which indicates to the code running on this computer that it is possible to switch to that architecture.
|
// Adds a new supported architecture, which indicates to the code running on this computer that it is possible to switch to that architecture.
|
||||||
void nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
void nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch);
|
||||||
// Returns the array of supported architectures, as well as the length.
|
// Returns the array of supported architectures, as well as the length.
|
||||||
@ -293,6 +293,8 @@ typedef enum nn_ComponentAction {
|
|||||||
NN_COMP_DEINIT,
|
NN_COMP_DEINIT,
|
||||||
// perform a method call
|
// perform a method call
|
||||||
NN_COMP_CALL,
|
NN_COMP_CALL,
|
||||||
|
// check if a method is enabled
|
||||||
|
NN_COMP_ENABLED,
|
||||||
} nn_ComponentAction;
|
} nn_ComponentAction;
|
||||||
|
|
||||||
typedef struct nn_ComponentRequest {
|
typedef struct nn_ComponentRequest {
|
||||||
@ -303,11 +305,19 @@ typedef struct nn_ComponentRequest {
|
|||||||
// the local state of the component. NN_COMP_INIT should initialize this pointer.
|
// the local state of the component. NN_COMP_INIT should initialize this pointer.
|
||||||
void *state;
|
void *state;
|
||||||
nn_Computer *computer;
|
nn_Computer *computer;
|
||||||
|
// address of the component
|
||||||
|
const char *compAddress;
|
||||||
|
// the action requested
|
||||||
nn_ComponentAction action;
|
nn_ComponentAction action;
|
||||||
// for NN_COMP_CALL, it is the method called.
|
// for NN_COMP_CALL, it is the method called.
|
||||||
|
// for NN_COMP_ENABLED, it is the method being checked.
|
||||||
const char *methodCalled;
|
const char *methodCalled;
|
||||||
// for NN_COMP_CALL, it is the amount of return values.
|
union {
|
||||||
size_t returnCount;
|
// for NN_COMP_CALL, it is the amount of return values.
|
||||||
|
size_t returnCount;
|
||||||
|
// for NN_COMP_ENABLED, it is whether the method is enabled.
|
||||||
|
bool methodEnabled;
|
||||||
|
};
|
||||||
} nn_ComponentRequest;
|
} nn_ComponentRequest;
|
||||||
|
|
||||||
typedef nn_Exit nn_ComponentHandler(nn_ComponentRequest *req);
|
typedef nn_Exit nn_ComponentHandler(nn_ComponentRequest *req);
|
||||||
@ -322,6 +332,10 @@ void nn_destroyComponentType(nn_ComponentType *ctype);
|
|||||||
nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentType *ctype, const char *address, size_t slot, void *userdata);
|
nn_Exit nn_addComponent(nn_Computer *computer, nn_ComponentType *ctype, const char *address, size_t slot, void *userdata);
|
||||||
// Checks if a component of that address exists.
|
// Checks if a component of that address exists.
|
||||||
bool nn_hasComponent(nn_Computer *computer, const char *address);
|
bool nn_hasComponent(nn_Computer *computer, const char *address);
|
||||||
|
// Checks if the component has that method.
|
||||||
|
// This not only checks if the method exists in the component type,
|
||||||
|
// but also checks if the method is enabled for the component instance.
|
||||||
|
bool nn_hasMethod(nn_Computer *computer, const char *address, const char *method);
|
||||||
// removes a component. Outside of the initialization state (aka after the first tick), it also emits the signal for component removed.
|
// removes a component. Outside of the initialization state (aka after the first tick), it also emits the signal for component removed.
|
||||||
nn_Exit nn_removeComponent(nn_Computer *computer, const char *address);
|
nn_Exit nn_removeComponent(nn_Computer *computer, const char *address);
|
||||||
// Gets the name of a type of a component.
|
// Gets the name of a type of a component.
|
||||||
|
|||||||
11
rewrite/nn_include.c
Normal file
11
rewrite/nn_include.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Includes all the C files to compile the entire library in one Compilation Unit
|
||||||
|
// this is better than LTO, but it requires more RAM and compute.
|
||||||
|
|
||||||
|
#include "nn_utils.h"
|
||||||
|
|
||||||
|
#if defined(__STDC_NO_THREADS__) || defined(NN_WINDOWS)
|
||||||
|
#include "tinycthread.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nn_utils.c"
|
||||||
|
#include "nn_model.c"
|
||||||
@ -12,5 +12,89 @@ nn_Universe *nn_createUniverse(nn_Context *ctx) {
|
|||||||
|
|
||||||
void nn_destroyUniverse(nn_Universe *universe) {
|
void nn_destroyUniverse(nn_Universe *universe) {
|
||||||
nn_Context ctx = universe->ctx;
|
nn_Context ctx = universe->ctx;
|
||||||
|
for(size_t i = 0; i < NN_BUILTIN_COUNT; i++) nn_destroyComponentType(universe->types[i]);
|
||||||
nn_free(&ctx, universe, sizeof(nn_Universe));
|
nn_free(&ctx, universe, sizeof(nn_Universe));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nn_ComponentType *nn_createComponentType(nn_Universe *universe, const char *name, void *userdata, const nn_ComponentMethod methods[], nn_ComponentHandler *handler) {
|
||||||
|
nn_Context *ctx = &universe->ctx;
|
||||||
|
char *namecpy = nn_strdup(ctx, name);
|
||||||
|
if(namecpy == NULL) return NULL;
|
||||||
|
|
||||||
|
size_t methodCount = 0;
|
||||||
|
while(methods[methodCount].name != NULL) methodCount++;
|
||||||
|
// include the terminator!
|
||||||
|
methodCount++;
|
||||||
|
size_t methodSize = sizeof(nn_ComponentMethod) * methodCount;
|
||||||
|
|
||||||
|
nn_ComponentMethod *methodscpy = nn_alloc(ctx, methodSize);
|
||||||
|
if(methodscpy == NULL) {
|
||||||
|
nn_strfree(ctx, namecpy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// in an ideal world, I'd just implement arenas.
|
||||||
|
// I should just implement arenas ngl
|
||||||
|
// TODO: just use arenas so memory management is ultra free
|
||||||
|
size_t methodIdx = 0;
|
||||||
|
while(methodIdx < methodCount) {
|
||||||
|
if(methods[methodIdx].name == NULL) {
|
||||||
|
methodscpy[methodIdx].name = NULL;
|
||||||
|
methodscpy[methodIdx].docString = NULL;
|
||||||
|
methodscpy[methodIdx].direct = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char *namecpy = nn_strdup(ctx, methods[methodIdx].name);
|
||||||
|
if(namecpy == NULL) goto methodOom;
|
||||||
|
char *doc = nn_strdup(ctx, methods[methodIdx].docString);
|
||||||
|
if(doc == NULL) {
|
||||||
|
nn_strfree(ctx, namecpy);
|
||||||
|
goto methodOom;
|
||||||
|
}
|
||||||
|
methodscpy[methodIdx].name = namecpy;
|
||||||
|
methodscpy[methodIdx].docString = doc;
|
||||||
|
methodscpy[methodIdx].direct = methods[methodIdx].direct;
|
||||||
|
methodIdx++;
|
||||||
|
}
|
||||||
|
goto normalExec;
|
||||||
|
methodOom:
|
||||||
|
for(size_t i = 0; i < methodIdx; i++) {
|
||||||
|
nn_strfree(ctx, (char *)methodscpy[i].name);
|
||||||
|
nn_strfree(ctx, (char *)methodscpy[i].docString);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
normalExec:;
|
||||||
|
|
||||||
|
nn_ComponentType *ctype = nn_alloc(ctx, sizeof(nn_ComponentType));
|
||||||
|
if(ctype == NULL) {
|
||||||
|
nn_strfree(ctx, namecpy);
|
||||||
|
nn_free(ctx, methodscpy, methodSize);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctype->name = namecpy;
|
||||||
|
ctype->methods = methodscpy;
|
||||||
|
ctype->universe = universe;
|
||||||
|
return ctype;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_destroyComponentType(nn_ComponentType *ctype) {
|
||||||
|
nn_Context *ctx = &ctype->universe->ctx;
|
||||||
|
|
||||||
|
nn_strfree(ctx, ctype->name);
|
||||||
|
|
||||||
|
size_t methodCount = 0;
|
||||||
|
while(ctype->methods[methodCount].name != NULL) {
|
||||||
|
nn_strfree(ctx, (char *)ctype->methods[methodCount].name);
|
||||||
|
nn_strfree(ctx, (char *)ctype->methods[methodCount].docString);
|
||||||
|
methodCount++;
|
||||||
|
}
|
||||||
|
// include the terminator!
|
||||||
|
methodCount++;
|
||||||
|
size_t methodSize = sizeof(nn_ComponentMethod) * methodCount;
|
||||||
|
nn_free(ctx, ctype->methods, methodSize);
|
||||||
|
|
||||||
|
nn_free(ctx, ctype, sizeof(nn_ComponentType));
|
||||||
|
}
|
||||||
|
|||||||
@ -13,6 +13,13 @@ typedef enum nn_BuiltinComponent {
|
|||||||
NN_BUILTIN_COUNT,
|
NN_BUILTIN_COUNT,
|
||||||
} nn_BuiltinComponent;
|
} nn_BuiltinComponent;
|
||||||
|
|
||||||
|
typedef struct nn_ComponentType {
|
||||||
|
nn_Universe *universe;
|
||||||
|
char *name;
|
||||||
|
// NULL-terminated
|
||||||
|
nn_ComponentMethod *methods;
|
||||||
|
} nn_ComponentType;
|
||||||
|
|
||||||
typedef struct nn_Universe {
|
typedef struct nn_Universe {
|
||||||
nn_Context ctx;
|
nn_Context ctx;
|
||||||
nn_ComponentType *types[NN_BUILTIN_COUNT];
|
nn_ComponentType *types[NN_BUILTIN_COUNT];
|
||||||
@ -20,6 +27,9 @@ typedef struct nn_Universe {
|
|||||||
|
|
||||||
typedef struct nn_Component {
|
typedef struct nn_Component {
|
||||||
char *address;
|
char *address;
|
||||||
|
nn_ComponentType *ctype;
|
||||||
|
size_t slot;
|
||||||
|
void *userdata;
|
||||||
} nn_Component;
|
} nn_Component;
|
||||||
|
|
||||||
// the values
|
// the values
|
||||||
@ -74,8 +84,10 @@ typedef struct nn_Computer {
|
|||||||
size_t totalMemory;
|
size_t totalMemory;
|
||||||
double creationTimestamp;
|
double creationTimestamp;
|
||||||
size_t stackSize;
|
size_t stackSize;
|
||||||
|
size_t archCount;
|
||||||
nn_Value callstack[NN_MAX_STACK];
|
nn_Value callstack[NN_MAX_STACK];
|
||||||
char errorBuffer[NN_MAX_ERROR_SIZE];
|
char errorBuffer[NN_MAX_ERROR_SIZE];
|
||||||
|
nn_Architecture archs[NN_MAX_ARCHITECTURES];
|
||||||
} nn_Computer;
|
} nn_Computer;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -31,6 +31,37 @@ void nn_free(nn_Context *ctx, void *memory, size_t size) {
|
|||||||
ctx->alloc(ctx->state, memory, size, 0);
|
ctx->alloc(ctx->state, memory, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t nn_strlen(const char *s) {
|
||||||
|
size_t l = 0;
|
||||||
|
while(*(s++) != '\0') l++;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *nn_strdup(nn_Context *ctx, const char *s) {
|
||||||
|
size_t l = nn_strlen(s);
|
||||||
|
char *buf = nn_alloc(ctx, sizeof(char) * (l+1));
|
||||||
|
if(buf == NULL) return NULL;
|
||||||
|
nn_memcpy(buf, s, sizeof(char) * l);
|
||||||
|
buf[l] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_strfree(nn_Context *ctx, char *s) {
|
||||||
|
size_t l = nn_strlen(s);
|
||||||
|
nn_free(ctx, s, sizeof(char) * (l+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_memcpy(void *dest, const void *src, size_t len) {
|
||||||
|
char *out = (char *)dest;
|
||||||
|
const char *in = (const char *)src;
|
||||||
|
for(size_t i = 0; i < len; i++) out[i] = in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn_memset(void *dest, int x, size_t len) {
|
||||||
|
char *out = (char *)dest;
|
||||||
|
for(size_t i = 0; i < len; i++) out[i] = (char)x;
|
||||||
|
}
|
||||||
|
|
||||||
nn_Lock *nn_createLock(nn_Context *ctx) {
|
nn_Lock *nn_createLock(nn_Context *ctx) {
|
||||||
void *mem = nn_alloc(ctx, ctx->lockSize);
|
void *mem = nn_alloc(ctx, ctx->lockSize);
|
||||||
if(mem == NULL) return NULL;
|
if(mem == NULL) return NULL;
|
||||||
|
|||||||
@ -7,6 +7,13 @@ void *nn_alloc(nn_Context *ctx, size_t size);
|
|||||||
void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize);
|
void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize);
|
||||||
void nn_free(nn_Context *ctx, void *memory, size_t size);
|
void nn_free(nn_Context *ctx, void *memory, size_t size);
|
||||||
|
|
||||||
|
size_t nn_strlen(const char *s);
|
||||||
|
char *nn_strdup(nn_Context *ctx, const char *s);
|
||||||
|
void nn_strfree(nn_Context *ctx, char *s);
|
||||||
|
|
||||||
|
void nn_memcpy(void *dest, const void *src, size_t len);
|
||||||
|
void nn_memset(void *dest, int x, size_t len);
|
||||||
|
|
||||||
typedef struct nn_Lock nn_Lock;
|
typedef struct nn_Lock nn_Lock;
|
||||||
|
|
||||||
nn_Lock *nn_createLock(nn_Context *ctx);
|
nn_Lock *nn_createLock(nn_Context *ctx);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user