From 2802c8e8bb987206da0991129e30f0c198cd8f37 Mon Sep 17 00:00:00 2001 From: physick Date: Tue, 28 Jul 2026 01:07:07 +0500 Subject: versioning fix --- src/main.c | 7 ++-- src/puzzles/puzzle.h | 14 +------ src/wren_inter/wren_inter.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ src/wren_inter/wren_inter.h | 14 ++++++- 4 files changed, 116 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 837c3d5..04e857c 100644 --- a/src/main.c +++ b/src/main.c @@ -3,9 +3,6 @@ #include "scenes/scenes.h" #include "resources/resources.h" -#ifndef BUILD_VERSION -#define BUILD_VERSION "build UNTRACKED" -#endif // BUILD_VERSION int main(void) { if (!InitSceneStack()) { @@ -36,7 +33,9 @@ int main(void) { BeginDrawing(); DrawScene(); DrawFPS(0, 0); - DrawText(BUILD_VERSION, 0, GetScreenHeight() - 20, 20, COLORSCHEME_BROWN); + #ifdef BUILD_VERSION + DrawText(BUILD_VERSION, 0, GetScreenHeight() - 20, 20, COLORSCHEME_BROWN); + #endif // BUILD_VERSION EndDrawing(); } diff --git a/src/puzzles/puzzle.h b/src/puzzles/puzzle.h index 838b9d2..181c0ae 100644 --- a/src/puzzles/puzzle.h +++ b/src/puzzles/puzzle.h @@ -1,18 +1,9 @@ #include #include +#include "../wren_inter/wren_inter.h" #ifndef PUZZLE_H - -enum PUZZLE_TEST_RESULT : char { - RESULT_OK = 0, - RESULT_WRONG_ANSWER, - RESULT_COMPTIME_NO_ENTRY, - RESULT_COMPTIME_ERR, - RESULT_RUNTIME_ERR, - // TODO: add async evaluation to prevent `while (true)` situation - RESULT_TIMEOUT, - RESULT_INIT_ERROR, -}; +#define PUZZLE_H // This is a param that would be placed in a slot // https://wren.io/embedding/slots-and-handles.html#writing-slots @@ -67,5 +58,4 @@ typedef struct { SubmitionResult *SubmitSolution(Puzzle *self, char *script); void FreeSunmitionResult(SubmitionResult *res); -#define PUZZLE_H #endif // PUZZLE_H diff --git a/src/wren_inter/wren_inter.c b/src/wren_inter/wren_inter.c index 10ecc93..868b2fe 100644 --- a/src/wren_inter/wren_inter.c +++ b/src/wren_inter/wren_inter.c @@ -33,6 +33,7 @@ void errorFn(WrenVM* vm, WrenErrorType errorType, } } +// Obsolete char *EvaluateScript(char *script) { TraceLog(LOG_INFO, "Evaluating %s...", script); WrenVM *vm = InterpreterPrepareMachine(); @@ -77,3 +78,100 @@ void InterpreterFreeMachine(WrenVM *vm) { if (sb != NULL && sb->val != NULL) free(sb); wrenFreeVM(vm); } + +// ========== Async ========== + +typedef struct { + // The data that you want to access in the worker + void *data; + // Toggle this to true when the task is finished + bool is_done; +} Task; + +bool RunWithCancellation(Task *task, void *(*runner) (void *), int timeout); + +#if defined(unix) || defined(__unix__) || defined(__unix) + +#include +#include +#include + +// Returns false if the process was aborted +bool RunWithCancellation(Task *task, void *(*runner) (void *), int timeout) { + pthread_t thread_id; + if (pthread_create(&thread_id, NULL, runner, &task) != 0) { + TraceLog(LOG_ERROR, "Failed to create a pthread"); + return RESULT_INIT_ERROR; + } + + int elapsed = 0; + while (!task->is_done && elapsed < timeout) { + sleep(1); + elapsed += 1; + } + + if (!task->is_done) { + pthread_cancel(thread_id); + pthread_join(thread_id, NULL); + return false; + } + + return true; +} + +#endif + +// The task that the interpreter would need to run. Made for async reasons +typedef struct { + WrenVM *vm; + const char *module; + const char *script; + WrenInterpretResult result; + bool is_done; +} wrenTask; + +// Runs the wrenTask asynchronously +// FIX: Inject the cancellation parameters inside the worker thread definition +void *wren_worker(void *arg) { + int old_type; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type); // + + Task *task_raw = (Task*)arg; + wrenTask *task = (wrenTask*)task_raw->data; + task->result = wrenInterpret(task->vm, task->module, task->script); + task_raw->is_done = true; + return NULL; +} + + +enum PUZZLE_TEST_RESULT wrenInterpretLimited(WrenVM* vm, const char* module, + const char* script, int sMax) { + + wrenTask *data = malloc(sizeof(wrenTask)); + data->vm = vm; + data->module = module; + data->script = script; + data->result = 0; + + Task *task = malloc(sizeof(Task)); + task->is_done = false; + task->data = data; + + if (!RunWithCancellation(task, wren_worker, sMax)) { + return RESULT_TIMEOUT; + } + + WrenInterpretResult interpret_res = data->result; + + free(data); + free(task); + + switch (interpret_res) { + case WREN_RESULT_COMPILE_ERROR: + return RESULT_COMPTIME_ERR; + case WREN_RESULT_RUNTIME_ERROR: + return RESULT_RUNTIME_ERR; + default: break; + } + return RESULT_OK; +} diff --git a/src/wren_inter/wren_inter.h b/src/wren_inter/wren_inter.h index 100f946..a84323f 100644 --- a/src/wren_inter/wren_inter.h +++ b/src/wren_inter/wren_inter.h @@ -3,10 +3,22 @@ #include -char *EvaluateScript(char *script); +enum PUZZLE_TEST_RESULT { + RESULT_OK = 0, + RESULT_WRONG_ANSWER, + RESULT_COMPTIME_NO_ENTRY, + RESULT_COMPTIME_ERR, + RESULT_RUNTIME_ERR, + // TODO: add async evaluation to prevent `while (true)` situation + RESULT_TIMEOUT, + RESULT_INIT_ERROR, +}; WrenVM *InterpreterPrepareMachine(); char *GetMachineOutput(WrenVM *vm); void InterpreterFreeMachine(WrenVM *vm); +// Runs the machine and returns +enum PUZZLE_TEST_RESULT wrenInterpretLimited(WrenVM *vm, const char *module, + const char *script, int sMax); #endif // WREN_INTER_H -- cgit v1.3