diff --git a/prosperon/prosperon.ce b/prosperon/prosperon.ce index c64c28fa..62e20738 100644 --- a/prosperon/prosperon.ce +++ b/prosperon/prosperon.ce @@ -11,13 +11,14 @@ var video $_.start(e => { if (e.type !== 'greet') return video = e.actor - loop() graphics = use('graphics', video) send(video, {kind:"window", op:"makeRenderer"}, e => { log.console("MADE A WINDOW! so now renderer") $_.start(e => { if (gameactor) return gameactor = e.actor + $_.couple(gameactor) + loop() }, args[0]) }) }, 'prosperon/sdl_video', { @@ -100,13 +101,6 @@ var graphics var gameactor -var last = time.number() - -// FPS tracking -var fps_samples = [] -var fps_sample_count = 60 -var fps_sum = 0 - var images = {} // Convert high-level draw commands to low-level renderer commands @@ -243,21 +237,19 @@ function translate_draw_commands(commands) { function loop(time) { - log.console("LOOP") send(video, {kind:'input', op:'get'}, e => { for (var event of e) { if (event.type === 'quit') $_.stop() } - log.console(json.encode(e)) }) - if (!gameactor) { - $_.clock(loop) - return - } + send(gameactor, {kind:'update', dt:1/60}); + $_.delay(loop, 1/60); + return; + // Update the game - send(gameactor, {kind:'update', dt:1/60}, e => { + send(gameactor, {kind:'che', dt:1/60}, e => { // Get draw commands from game send(gameactor, {kind:'draw'}, draw_commands => { var batch_commands = [] @@ -287,10 +279,11 @@ function loop(time) op: "batch", data: batch_commands }, _ => { - $_.clock(loop) }) }) }) + + $_.delay(loop, 1/30) } $_.receiver(e => { @@ -304,6 +297,4 @@ $_.receiver(e => { if (e.d_pos) e.d_pos.y *= -1 } - - send(gameactor, e) }) \ No newline at end of file diff --git a/prosperon/sdl_video.ce b/prosperon/sdl_video.ce index 06423fc1..43024386 100644 --- a/prosperon/sdl_video.ce +++ b/prosperon/sdl_video.ce @@ -61,13 +61,6 @@ var default_window = { var config = Object.assign({}, default_window, arg[0] || {}); win = new video.window(config); -log.console(win.title) -log.console(win.size) -log.console(win.visible) -log.console(win.minimized) -log.console(win.position) -win.maximized = true - // Resource tracking var resources = { texture: {}, diff --git a/scripts/engine.cm b/scripts/engine.cm index bf946983..5267c560 100644 --- a/scripts/engine.cm +++ b/scripts/engine.cm @@ -92,11 +92,11 @@ function disrupt(err) var reason = (err instanceof Error) ? err.stack : err report_to_overling({type:'disrupt', reason}) } - - log.error(err) - - log.console("DISRUPTING") - + + log.console(err); + if (err.stack) + log.console(err.stack) + actor_mod.disrupt() } diff --git a/source/cell.c b/source/cell.c index 563dec85..799a2f97 100644 --- a/source/cell.c +++ b/source/cell.c @@ -18,6 +18,19 @@ #include // perror(), printf() #include // exit() +#ifdef __APPLE__ +#include +#include +#endif + +#ifdef _WIN32 +#include +#endif + +#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__linux__) +#include +#endif + #include #define WOTA_IMPLEMENTATION @@ -156,22 +169,6 @@ void actor_free(cell_rt *actor) SDL_UnlockMutex(actors_mutex); } -JSValue js_actor_remove_cb(JSContext *js, JSValue this_val, int argc, JSValue *argv) -{ - cell_rt *actor = JS_GetContextOpaque(js); - - if (JS_IsUndefined(actor->unneeded)) - actor_free(actor); - else { - SDL_LockMutex(actor->mutex); - JSValue ret = JS_Call(actor->context, actor->unneeded, JS_UNDEFINED, 0, NULL); - uncaught_exception(actor->context, ret); - SDL_UnlockMutex(actor->mutex); - actor_free(actor); - } - return JS_UNDEFINED; -} - void js_dofree(JSRuntime *rt, void *opaque, void *ptr) { js_free_rt(rt, ptr); @@ -386,6 +383,7 @@ const char *send_message(const char *id, void *msg) l.wota_data = msg; SDL_LockMutex(target->msg_mutex); + arrput(target->letters, l); if (target->ar) { remove_timer(target->ar); @@ -406,7 +404,8 @@ static Uint32 actor_remove_cb(Uint32 id, Uint32 interval, cell_rt *actor) uncaught_exception(actor->context, ret); SDL_UnlockMutex(actor->mutex); } - actor_free(actor); + + actor_disrupt(actor); return 0; } @@ -432,10 +431,6 @@ Uint32 actor_delay_cb(SDL_TimerID id, Uint32 interval, cell_rt *actor) void set_actor_state(cell_rt *actor) { - if (actor->disrupt) { - actor_free(actor); - return; - } SDL_LockMutex(actor->msg_mutex); switch(actor->state) { @@ -502,10 +497,12 @@ void actor_turn(cell_rt *actor) JS_FreeValue(actor->context, l.callback); } - // now idle - actor->state = ACTOR_IDLE; - SDL_UnlockMutex(actor->mutex); + + // now idle + SDL_LockMutex(actor->msg_mutex); + actor->state = ACTOR_IDLE; + SDL_UnlockMutex(actor->msg_mutex); #ifdef TRACY_ENABLE if (tracy_profiling_enabled) @@ -625,6 +622,10 @@ void tracy_end_hook(JSContext *js, JSValue fn) void actor_disrupt(cell_rt *crt) { crt->disrupt = 1; + + printf("actor %s disrupted\n", crt->id); + + actor_free(crt); } static int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt) @@ -694,7 +695,10 @@ int uncaught_exception(JSContext *js, JSValue v) return 1; } + printf("UNCAUGHT EXCEPTION IN ACTOR %s\n", rt->id); + JSValue exp = JS_GetException(js); + JSValue ret = JS_Call(js, rt->on_exception, JS_UNDEFINED, 1, &exp); JS_FreeValue(js,ret); JS_FreeValue(js, exp); @@ -724,6 +728,8 @@ static int actor_runner(void *data) static void signal_handler(int sig) { + printf("SIG %d\n", sig); + exit_handler(); const char *str = NULL; switch (sig) { case SIGABRT: str = "SIGABRT"; break; @@ -757,6 +763,7 @@ queue_cond = SDL_CreateCondition(); mainqueue_mutex = SDL_CreateMutex(); mainqueue_cond = SDL_CreateCondition(); actors_mutex = SDL_CreateMutex(); +timer_init(); add_runners(SDL_GetNumLogicalCPUCores()-1); @@ -889,7 +896,6 @@ int main(int argc, char **argv) signal(SIGTERM, signal_handler); signal(SIGSEGV, signal_handler); signal(SIGABRT, signal_handler); - atexit(exit_handler); loop(); diff --git a/source/timer.c b/source/timer.c index 05907b6d..95bc43cb 100644 --- a/source/timer.c +++ b/source/timer.c @@ -28,12 +28,12 @@ uint64_t get_time_ns(void) Uint32 add_timer_ns(uint64_t delay_ns, TimerCallback callback, void *param) { timer_t t; + SDL_LockMutex(timer_mutex); t.id = next_timer_id++; t.interval_ns = delay_ns; t.due_ns = get_time_ns() + delay_ns; t.callback = callback; t.param = param; - SDL_LockMutex(timer_mutex); arrput(timers, t); SDL_UnlockMutex(timer_mutex); SDL_SignalCondition(mainqueue_cond); @@ -80,18 +80,21 @@ void process_due_timers(void) uint64_t next_timeout_ns(void) { - SDL_LockMutex(timer_mutex); - if (!timers || arrlen(timers) == 0) { - SDL_UnlockMutex(timer_mutex); - return UINT64_MAX; - } + uint64_t min_due = UINT64_MAX; uint64_t now = get_time_ns(); - uint64_t min_due = timers[0].due_ns; - for (int i = 1; i < arrlen(timers); i++) { - if (timers[i].due_ns < min_due) - min_due = timers[i].due_ns; + + SDL_LockMutex(timer_mutex); + if (timers && arrlen(timers) > 0) { + min_due = timers[0].due_ns; + for (int i = 1; i < arrlen(timers); i++) { + if (timers[i].due_ns < min_due) + min_due = timers[i].due_ns; + } } SDL_UnlockMutex(timer_mutex); + + if (min_due == UINT64_MAX) + return UINT64_MAX; if (min_due <= now) return 0; return min_due - now; diff --git a/tests/blob.ce b/tests/blob.ce index 08dadd22..67af21f0 100644 --- a/tests/blob.ce +++ b/tests/blob.ce @@ -406,4 +406,4 @@ log.console("Passed: " + passed); log.console("Failed: " + failed); log.console("\nOverall: " + (failed === 0 ? "PASSED" : "FAILED")); -os.exit(failed === 0 ? 0 : 1); \ No newline at end of file +$_.stop() \ No newline at end of file