From 1d491e694a5c116c05e10e8cbbfba50dd4ee94b5 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 27 Nov 2023 23:04:04 +0000 Subject: [PATCH] Fix race condition for sound ending --- scripts/ai.js | 45 +++++++++++++++++++++----------------- scripts/engine.js | 1 + scripts/entity.js | 1 + scripts/sound.js | 11 +++++++++- source/engine/datastream.h | 1 - source/engine/jsffi.c | 12 ++++++++++ source/engine/script.c | 27 ++++++++++++++++++----- source/engine/script.h | 2 +- source/engine/yugine.c | 2 ++ 9 files changed, 74 insertions(+), 28 deletions(-) diff --git a/scripts/ai.js b/scripts/ai.js index 7f8f365..b4617ae 100644 --- a/scripts/ai.js +++ b/scripts/ai.js @@ -1,16 +1,8 @@ var AI = { - tick() { - - }, - - sequence(list) { - - }, - race(list) { - return function() { + return function(dt) { var good = false; - list.forEach(x => if (x()) good = true); + list.forEach(function(x) { if (x.call(this,dt)) good = true; }, this); return good; }; }, @@ -18,21 +10,34 @@ var AI = { do(times, list) { }, - - sync(list) { - return function() { + + sequence(list) { + var i = 0; + return function(dt) { + while (i !== list.length) { + if (list[i].call(this,dt)) + i++; + else + return false; + } + return true; + }; + }, + + parallel(list) { + return function(dt) { var good = true; - list.forEach(x => if (!x()) good = false); + list.forEach(function(x){ if (!x.call(this,dt)) good = false; },this); return good; }; }, - moveto(pos) { - return function() { - var dir = pos.sub(this.pos); + moveto() { + return function(dt) { + var dir = this.randomloc.sub(this.pos); if (Vector.length(dir) < 10) return true; - this.velocity = Vector.normalize(pos.sub(this.pos)).scale(20); + this.velocity = Vector.norm(this.randomloc.sub(this.pos)).scale(20); return false; } }, @@ -40,8 +45,8 @@ var AI = { wait(secs) { secs ??= 1; var accum = 0; - return function() { - accum += Game.dt; + return function(dt) { + accum += dt; if (accum >= secs) return true; diff --git a/scripts/engine.js b/scripts/engine.js index 2fa8668..68bf65f 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -470,6 +470,7 @@ Render.doc = { load("scripts/physics.js"); load("scripts/input.js"); load("scripts/sound.js"); +load("scripts/ai.js"); function screen2world(screenpos) { if (Game.camera) diff --git a/scripts/entity.js b/scripts/entity.js index 5ce8c26..6b9726f 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -62,6 +62,7 @@ var gameobject = { cry(file) { var p = Sound.play(file, Sound.bus.sfx); var killfn = p.kill.bind(p); + p.end = killfn; this.timers.push(killfn); return killfn; }, diff --git a/scripts/sound.js b/scripts/sound.js index 5b1fdf0..6d7e00a 100644 --- a/scripts/sound.js +++ b/scripts/sound.js @@ -17,17 +17,26 @@ var dsp_node = { kill() { if (this._dead) return; this._dead = true; - cmd(193, this.id); }, + cmd(193, this.id); + }, + end() {}, }; var dsp_source = Object.copy(dsp_node,{ end(){}, get loop() { return cmd(194,this.id); }, set loop(x) { cmd(195,this.id, x);}, + get frame() { return cmd(196,this.id); }, + set frame(x) { cmd(199, this.id, x); }, + frames() { return cmd(197,this.id); }, + length() { return this.frames()/Sound.samplerate(); }, + time() { return this.frame/Sound.samplerate(); }, + pct() { return this.time()/this.length(); }, }); var Sound = { bus: {}, + samplerate() { return cmd(198); }, sounds: [], /* array of loaded sound files */ play(file, bus) { if (!IO.exists(file)) { diff --git a/source/engine/datastream.h b/source/engine/datastream.h index e1cd5ac..fb5b3c2 100644 --- a/source/engine/datastream.h +++ b/source/engine/datastream.h @@ -4,7 +4,6 @@ #include #include #include "dsp.h" -#include "utringbuffer.h" #include "sokol/sokol_gfx.h" diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index b215ae7..b2c6448 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -1265,6 +1265,18 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 195: ((sound*)((dsp_node*)js2ptr(argv[1]))->data)->loop = js2bool(argv[2]); break; + case 196: + ret = num2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->frame); + break; + case 197: + ret = num2js(((sound*)((dsp_node*)js2ptr(argv[1]))->data)->data->frames); + break; + case 198: + ret = num2js(SAMPLERATE); + break; + case 199: + ((sound*)((dsp_node*)js2ptr(argv[1]))->data)->frame = js2number(argv[2]); + break; } if (str) diff --git a/source/engine/script.c b/source/engine/script.c index 3b621f1..60fb989 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -211,13 +211,30 @@ void script_eval_w_env(const char *s, JSValue env, const char *file) { JS_FreeValue(js, v); } +struct callenv { + JSValue v; + const char *eval; +}; + +struct callenv *calls; + +void call_stack() +{ + for (int i = 0; i < arrlen(calls); i++) { + JSValue v = JS_EvalThis(js, calls[i].v, calls[i].eval, strlen(calls[i].eval), calls[i].eval, JS_EVAL_FLAGS); + js_print_exception(v); + JS_FreeValue(js, v); + } + arrfree(calls); +} + void call_env(JSValue env, const char *eval) { - if (!JS_IsObject(env)) return; - JSValue fn = JS_GetPropertyStr(js, env, eval); - JSValue v = JS_EvalThis(js, env, eval, strlen(eval), "script", JS_EVAL_FLAGS); - js_print_exception(v); - JS_FreeValue(js,v); + if (!JS_IsObject(env)) { YughWarn("NOT AN ENV"); return; }; + struct callenv c; + c.v = env; + c.eval = eval; + arrpush(calls, c); } void file_eval_env(const char *file, JSValue env) diff --git a/source/engine/script.h b/source/engine/script.h index 2cd259e..b3a51a2 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -16,7 +16,7 @@ extern struct callee stacktrace_callee; extern JSValue num_cache[100]; JSValue jstr(const char *str); - +void call_stack(); void js_stacktrace(); void script_startup(); void script_stop(); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index f0e67ef..739a20c 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -162,6 +162,7 @@ int frame_fps() { static void process_frame() { double elapsed = stm_sec(stm_laptime(&frame_t)); + call_stack(); // ds_advance(bjork, elapsed); input_poll(0); /* Timers all update every frame - once per monitor refresh */ @@ -172,6 +173,7 @@ static void process_frame() double dt = stm_sec(stm_diff(frame_t, updatelast)); updatelast = frame_t; prof_start(&prof_update); + call_updates(dt * timescale); prof(&prof_update);