Fix race condition for sound ending

This commit is contained in:
John Alanbrook 2023-11-27 23:04:04 +00:00
parent 44febe1c6d
commit 1d491e694a
9 changed files with 74 additions and 28 deletions

View file

@ -1,16 +1,8 @@
var AI = { var AI = {
tick() {
},
sequence(list) {
},
race(list) { race(list) {
return function() { return function(dt) {
var good = false; var good = false;
list.forEach(x => if (x()) good = true); list.forEach(function(x) { if (x.call(this,dt)) good = true; }, this);
return good; return good;
}; };
}, },
@ -19,20 +11,33 @@ var AI = {
}, },
sync(list) { sequence(list) {
return function() { 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; var good = true;
list.forEach(x => if (!x()) good = false); list.forEach(function(x){ if (!x.call(this,dt)) good = false; },this);
return good; return good;
}; };
}, },
moveto(pos) { moveto() {
return function() { return function(dt) {
var dir = pos.sub(this.pos); var dir = this.randomloc.sub(this.pos);
if (Vector.length(dir) < 10) return true; 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; return false;
} }
}, },
@ -40,8 +45,8 @@ var AI = {
wait(secs) { wait(secs) {
secs ??= 1; secs ??= 1;
var accum = 0; var accum = 0;
return function() { return function(dt) {
accum += Game.dt; accum += dt;
if (accum >= secs) if (accum >= secs)
return true; return true;

View file

@ -470,6 +470,7 @@ Render.doc = {
load("scripts/physics.js"); load("scripts/physics.js");
load("scripts/input.js"); load("scripts/input.js");
load("scripts/sound.js"); load("scripts/sound.js");
load("scripts/ai.js");
function screen2world(screenpos) { function screen2world(screenpos) {
if (Game.camera) if (Game.camera)

View file

@ -62,6 +62,7 @@ var gameobject = {
cry(file) { cry(file) {
var p = Sound.play(file, Sound.bus.sfx); var p = Sound.play(file, Sound.bus.sfx);
var killfn = p.kill.bind(p); var killfn = p.kill.bind(p);
p.end = killfn;
this.timers.push(killfn); this.timers.push(killfn);
return killfn; return killfn;
}, },

View file

@ -17,17 +17,26 @@ var dsp_node = {
kill() { kill() {
if (this._dead) return; if (this._dead) return;
this._dead = true; this._dead = true;
cmd(193, this.id); }, cmd(193, this.id);
},
end() {},
}; };
var dsp_source = Object.copy(dsp_node,{ var dsp_source = Object.copy(dsp_node,{
end(){}, end(){},
get loop() { return cmd(194,this.id); }, get loop() { return cmd(194,this.id); },
set loop(x) { cmd(195,this.id, x);}, 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 = { var Sound = {
bus: {}, bus: {},
samplerate() { return cmd(198); },
sounds: [], /* array of loaded sound files */ sounds: [], /* array of loaded sound files */
play(file, bus) { play(file, bus) {
if (!IO.exists(file)) { if (!IO.exists(file)) {

View file

@ -4,7 +4,6 @@
#include <pl_mpeg.h> #include <pl_mpeg.h>
#include <stdint.h> #include <stdint.h>
#include "dsp.h" #include "dsp.h"
#include "utringbuffer.h"
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"

View file

@ -1265,6 +1265,18 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 195: case 195:
((sound*)((dsp_node*)js2ptr(argv[1]))->data)->loop = js2bool(argv[2]); ((sound*)((dsp_node*)js2ptr(argv[1]))->data)->loop = js2bool(argv[2]);
break; 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) if (str)

View file

@ -211,13 +211,30 @@ void script_eval_w_env(const char *s, JSValue env, const char *file) {
JS_FreeValue(js, v); 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) void call_env(JSValue env, const char *eval)
{ {
if (!JS_IsObject(env)) return; if (!JS_IsObject(env)) { YughWarn("NOT AN ENV"); return; };
JSValue fn = JS_GetPropertyStr(js, env, eval); struct callenv c;
JSValue v = JS_EvalThis(js, env, eval, strlen(eval), "script", JS_EVAL_FLAGS); c.v = env;
js_print_exception(v); c.eval = eval;
JS_FreeValue(js,v); arrpush(calls, c);
} }
void file_eval_env(const char *file, JSValue env) void file_eval_env(const char *file, JSValue env)

View file

@ -16,7 +16,7 @@ extern struct callee stacktrace_callee;
extern JSValue num_cache[100]; extern JSValue num_cache[100];
JSValue jstr(const char *str); JSValue jstr(const char *str);
void call_stack();
void js_stacktrace(); void js_stacktrace();
void script_startup(); void script_startup();
void script_stop(); void script_stop();

View file

@ -162,6 +162,7 @@ int frame_fps() {
static void process_frame() static void process_frame()
{ {
double elapsed = stm_sec(stm_laptime(&frame_t)); double elapsed = stm_sec(stm_laptime(&frame_t));
call_stack();
// ds_advance(bjork, elapsed); // ds_advance(bjork, elapsed);
input_poll(0); input_poll(0);
/* Timers all update every frame - once per monitor refresh */ /* 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)); double dt = stm_sec(stm_diff(frame_t, updatelast));
updatelast = frame_t; updatelast = frame_t;
prof_start(&prof_update); prof_start(&prof_update);
call_updates(dt * timescale); call_updates(dt * timescale);
prof(&prof_update); prof(&prof_update);