diff --git a/src/computer.c b/src/computer.c index 577d21e..2f8faa9 100644 --- a/src/computer.c +++ b/src/computer.c @@ -4,16 +4,72 @@ #include nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, size_t memoryLimit, size_t componentLimit); -void nn_tickComputer(nn_computer *computer); -double nn_getUptime(nn_computer *computer); -size_t nn_getComputerMemoryUsed(nn_computer *computer); -size_t nn_getComputerMemoryTotal(nn_computer *computer); -void *nn_getComputerUserData(nn_computer *computer); -void nn_addSupportedArchitecture(nn_computer *computer, nn_architecture *arch); -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_setTmpAddress(nn_computer *computer, nn_address tmp) { + nn_free(computer->tmpAddress); + computer->tmpAddress = nn_strdup(tmp); +} + +nn_address nn_getComputerAddress(nn_computer *computer) { + return computer->tmpAddress; +} + +int nn_tickComputer(nn_computer *computer) { + nn_clearError(computer); + computer->arch->tick(computer, computer->archState, computer->arch->userdata); + return nn_getState(computer); +} + +double nn_getUptime(nn_computer *computer) { + return nn_getTime(computer->universe) - computer->timeOffset; +} + +size_t nn_getComputerMemoryUsed(nn_computer *computer) { + return computer->arch->getMemoryUsage(computer, computer->archState, computer->arch->userdata); +} + +size_t nn_getComputerMemoryTotal(nn_computer *computer) { + return computer->memoryTotal; +} + +void *nn_getComputerUserData(nn_computer *computer) { + return computer->userdata; +} + +void nn_addSupportedArchitecture(nn_computer *computer, nn_architecture *arch) { + if(computer->supportedArchCount == NN_MAX_ARCHITECTURES) return; + computer->supportedArch[computer->supportedArchCount] = arch; + computer->supportedArchCount++; +} + +nn_architecture *nn_getArchitecture(nn_computer *computer) { + return computer->arch; +} + +nn_architecture *nn_getNextArchitecture(nn_computer *computer) { + return computer->nextArch; +} + +void nn_setNextArchitecture(nn_computer *computer, nn_architecture *arch) { + computer->nextArch = arch; +} + +void nn_deleteComputer(nn_computer *computer) { + nn_clearError(computer); + nn_resetCall(computer); + while(computer->signalCount > 0) { + nn_popSignal(computer); + } + for(size_t i = 0; i < computer->userCount; i++) { + nn_free(computer->users[i]); + } + computer->arch->teardown(computer, computer->archState, computer->arch->userdata); + nn_deleteGuard(computer->lock); + nn_free(computer->components); + nn_free(computer->address); + nn_free(computer->tmpAddress); + nn_free(computer); +} const char *nn_pushSignal(nn_computer *computer, nn_value *values, size_t len) { if(len > NN_MAX_SIGNAL_VALS) return "too many values"; @@ -221,3 +277,19 @@ size_t nn_getArgumentCount(nn_computer *computer) { size_t nn_getReturnCount(nn_computer *computer) { return computer->retc; } + +char *nn_serializeProgram(nn_computer *computer) { + return computer->arch->serialize(computer, computer->archState, computer->arch->userdata); +} + +void nn_deserializeProgram(nn_computer *computer, char *memory) { + computer->arch->deserialize(computer, memory, computer->archState, computer->arch->userdata); +} + +void nn_lockComputer(nn_computer *computer) { + nn_lock(computer->lock); +} + +void nn_unlockComputer(nn_computer *computer) { + nn_unlock(computer->lock); +} diff --git a/src/computer.h b/src/computer.h index af11856..a9322e4 100644 --- a/src/computer.h +++ b/src/computer.h @@ -12,6 +12,7 @@ typedef struct nn_computer { char state; bool allocatedError; char *err; + void *userdata; nn_guard *lock; nn_component *components; size_t componentLen; @@ -21,8 +22,9 @@ typedef struct nn_computer { nn_value rets[NN_MAX_RETS]; size_t retc; nn_architecture *arch; + void *archState; nn_architecture *nextArch; - nn_architecture supportedArch[NN_MAX_ARCHITECTURES]; + nn_architecture *supportedArch[NN_MAX_ARCHITECTURES]; size_t supportedArchCount; double timeOffset; nn_universe *universe; @@ -32,6 +34,9 @@ typedef struct nn_computer { size_t maxEnergy; nn_signal signals[NN_MAX_SIGNALS]; size_t signalCount; + size_t memoryTotal; + nn_address address; + nn_address tmpAddress; } nn_computer; #endif diff --git a/src/neonucleus.h b/src/neonucleus.h index f903ba2..6d1a94e 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -150,7 +150,7 @@ void nn_setClock(nn_universe *universe, nn_clock_t *clock, void *userdata); double nn_getTime(nn_universe *universe); nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, size_t memoryLimit, size_t componentLimit); -void nn_tickComputer(nn_computer *computer); +int nn_tickComputer(nn_computer *computer); double nn_getUptime(nn_computer *computer); size_t nn_getComputerMemoryUsed(nn_computer *computer); size_t nn_getComputerMemoryTotal(nn_computer *computer); @@ -169,6 +169,13 @@ void nn_deleteUser(nn_computer *computer, const char *name); const char *nn_indexUser(nn_computer *computer, size_t idx); bool nn_isUser(nn_computer *computer, const char *name); +/* The memory returned can be freed with nn_free() */ +char *nn_serializeProgram(nn_computer *computer); +void nn_deserializeProgram(nn_computer *computer, char *memory); + +void nn_lockComputer(nn_computer *computer); +void nn_unlockComputer(nn_computer *computer); + /// This means the computer has not yet started. /// This is used to determine whether newComponent and removeComponent should emit signals. #define NN_STATE_SETUP 0 @@ -225,6 +232,8 @@ void nn_setCError(nn_computer *computer, const char *err); // Component stuff nn_component *nn_newComponent(nn_computer *computer, nn_address address, int slot, nn_componentTable *table, void *userdata); +void nn_setTmpAddress(nn_computer *computer, nn_address tmp); +nn_address nn_getComputerAddress(nn_computer *computer); void nn_removeComponent(nn_computer *computer, nn_address address); void nn_destroyComponent(nn_component *component); nn_computer *nn_getComputerOfComponent(nn_component *component);