quickjs log to its own file; cleanup script.c

This commit is contained in:
John Alanbrook 2024-03-15 10:51:04 -05:00
parent bad225b965
commit 32b0cc7377
18 changed files with 338 additions and 608 deletions

View file

@ -101,11 +101,10 @@ Object.mixin(cmd(268,true), {
f = (f+1)%playing.frames.length;
if (f === 0)
sp.anim_done?.();
sp.gameobject?.delay(advance, playing.frames[f].time);
sp.ddd = sp.gameobject?.delay(advance, playing.frames[f].time);
}
advance();
},
stop() {},
set path(p) {
p = Resources.find_image(p);
if (!p) return;
@ -119,6 +118,11 @@ Object.mixin(cmd(268,true), {
get path() {
return this.tex.path();
},
kill() {
this.anim = undefined;
this.ddd?.();
delete this.ddd;
},
toString() { return "sprite"; },
move(d) { this.pos = this.pos.add(d); },
grow(x) {

View file

@ -86,8 +86,8 @@ function assert(op, str)
Debug.Options = { };
Debug.Options.Color = {
set trigger(x) { cmd(17,x); },
set debug(x) { cmd(16, x); },
//set trigger(x) { cmd(17,x); },
//set debug(x) { cmd(16, x); },
};
var Gizmos = {
@ -219,9 +219,9 @@ Debug.inputs.f9 = function() {
Debug.Options.gif.stop();
}
Debug.inputs.f10 = function() { Time.timescale = 0.1; };
Debug.inputs.f10 = function() { time.timescale = 0.1; };
Debug.inputs.f10.doc = "Toggle timescale to 1/10.";
Debug.inputs.f10.released = function () { Time.timescale = 1.0; };
Debug.inputs.f10.released = function () { time.timescale = 1.0; };
Debug.inputs.f12 = function() { GUI.defaults.debug = !GUI.defaults.debug; console.warn("GUI toggle debug");};
Debug.inputs.f12.doc = "Toggle drawing GUI debugging aids.";

View file

@ -66,7 +66,7 @@ function use(file)
var c = io.slurp(file);
var script = `(function() { ${c} })();`;
use.files[file] = cmd(123,script,global,file);
use.files[file] = cmd(123,file,global,script);
return use.files[file];
}
@ -86,7 +86,7 @@ function eval_env(script, env, file)
file ??= "SCRIPT";
console.info(`eval ${file}`);
script = `(function() { ${script}; }).call(this);\n`;
return cmd(123,script,env,file);
return cmd(123,file,env,script);
}
global.check_registers = function(obj)
@ -144,10 +144,15 @@ Object.assign(global, use("scripts/base.js"));
global.obscure('global');
global.mixin("scripts/render.js");
function process()
{
say ('holy cow');
}
global.Game = {
engine_start(fn) {
console.info("Starting rendering and sound ...");
cmd(257, fn);
cmd(257, fn, process);
},
object_count() {
@ -277,6 +282,7 @@ prosperon.touchpress = function(touches){};
prosperon.touchrelease = function(touches){};
prosperon.touchmove = function(touches){};
prosperon.clipboardpaste = function(str){};
prosperon.quit = function(){};
global.mixin("scripts/input.js");
global.mixin("scripts/std.js");
@ -295,7 +301,7 @@ var timer = {
kill() {
this.end();
this.fn = undefined;
delete this.fn;
},
delay(fn, secs) {
@ -304,7 +310,9 @@ var timer = {
t.remain = secs;
t.fn = fn;
t.end = Register.update.register(timer.update.bind(t));
return function() { t.kill(); };
var returnfn = timer.kill.bind(t);
returnfn.remain = secs;
return returnfn;
},
};
@ -313,59 +321,11 @@ global.mixin("scripts/physics.js");
global.mixin("scripts/ai.js");
global.mixin("scripts/geometry.js");
/*
Factory for creating registries. Register one with 'X.register',
which returns a function that, when invoked, cancels the registry.
*/
var Register = {
kbm_input(mode, btn, state, ...args) {
if (state === 'released') {
btn = btn.split('-').last();
}
switch(mode) {
case "emacs":
player[0].raw_input(btn, state, ...args);
break;
case "mouse":
player[0].mouse_input(btn, state, ...args);
break;
case "char":
player[0].char_input(btn);
break;
};
},
gamepad_playermap: [],
gamepad_input(pad, btn, state, ...args) {
var player = this.gamepad_playermap[pad];
if (!player) return;
var statestr = Input.state2str(state);
var rawfn = `gamepad_${btn}_${statestr}`;
player.input(rawfn, ...args);
input.action.actions.forEach(x => {
if (x.inputs.includes(btn))
player.input(`action_${x.name}_${statestr}`, ...args);
});
},
unregister_obj(obj) { Player.uncontrol(obj); },
endofloop(fn) {
if (!this.inloop)
fn();
else {
this.loopcbs.push(fn);
}
},
clear() {
Register.registries.forEach(function(n) {
n.entries = [];
});
},
registries: [],
add_cb(name) {
@ -394,11 +354,8 @@ Register.add_cb("appupdate");
Register.add_cb("physupdate");
Register.add_cb("gui");
Register.add_cb("debug");
Register.add_cb("gamepad_input");
Register.add_cb("draw");
Register.gamepad_playermap[0] = Player.players[0];
var Event = {
events: {},

View file

@ -217,9 +217,23 @@ var gameobject = {
},
delay(fn, seconds) {
var t = timer.delay(fn.bind(this), seconds);
this.timers.push(t);
return t;
var timescale = this.timescale;
var timers = this.timers;
var thisfn = fn.bind(this);
var rm_register;
var ud = function(dt) {
seconds -= dt*timescale;
if (seconds <= 0) {
thisfn();
rm_register();
rm_register = undefined;
thisfn = undefined;
}
}
rm_register = Register.update.register(ud);
return rm_register;
},
tween(prop, values, def) {
@ -602,6 +616,7 @@ var gameobject = {
this.components[key].kill?.();
this.components[key].gameobject = undefined;
delete this.components[key];
delete this[key];
}
this.clear();

View file

@ -67,7 +67,6 @@ function modstr()
prosperon.keydown = function(key, repeat)
{
prosperon.keys[key] = true;
if (key == 341 || key == 345)

View file

@ -41,6 +41,7 @@ os.prefpath = function() {
var projectfile = ".prosperon/project.json";
var Resources = {};
Resources.scripts = ["jso", "js"];
Resources.images = ["png", "gif", "jpg", "jpeg"];
Resources.sounds = ["wav", 'flac', 'mp3', "qoa"];
Resources.scripts = "js";
@ -61,6 +62,7 @@ function find_ext(file, ext)
Resources.find_image = function(file) { return find_ext(file,Resources.images); }
Resources.find_sound = function(file) { return find_ext(file,Resources.sounds); }
Resources.find_script = function(file) { return find_ext(file,Resources.scripts); }
Resources.is_sound = function(path) {
var ext = path.ext();

View file

@ -227,7 +227,7 @@ void constraint_break(constraint *constraint)
cpSpaceRemoveConstraint(space, constraint->c);
cpConstraintFree(constraint->c);
constraint->c = NULL;
script_call_sym(constraint->break_cb);
script_call_sym(constraint->break_cb,0,NULL);
}
void constraint_free(constraint *constraint)
@ -642,7 +642,7 @@ JSValue arb2js(cpArbiter *arb)
void phys_run_post(cpSpace *space, JSValue *fn, JSValue *hit)
{
script_call_fn_arg(*fn, *hit);
script_call_sym(*fn, 1, hit);
JS_FreeValue(js, *hit);
}

View file

@ -11,6 +11,7 @@
#include <fcntl.h>
#include "yugine.h"
#include "resources.h"
#include "quickjs/quickjs.h"
#include "script.h"
@ -41,10 +42,8 @@ void log_init()
#ifndef NDEBUG
logout = fopen(".prosperon/log.txt", "w");
writeout = fopen(".prosperon/transcript.txt", "w");
/* int og = dup(1);
close(1);
int fd = open("out.txt", O_WRONLY | O_CREAT, 0644);
dup2(fd, 1);*/
dump = fopen(".prosperon/quickjs.txt", "w");
quickjs_set_dumpout(dump);
#endif
}
@ -52,6 +51,7 @@ void log_shutdown()
{
fclose(logout);
fclose(writeout);
fclose(dump);
}
const char *logfmt = "%s:%d: [%s] %s, %s: ";

View file

@ -659,11 +659,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
size_t plen = 0;
switch (cmd) {
case 0:
str = JS_ToCString(js, argv[1]);
ret = JS_NewInt64(js, script_dofile(str));
break;
case 4:
debug_draw_phys(JS_ToBool(js, argv[1]));
break;
@ -672,11 +667,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
gameobject_draw_debug(js2gameobject(argv[1]));
break;
case 16:
str = js2str(argv[1]);
file_eval_env(str,argv[2]);
break;
case 17:
sapp_set_mouse_cursor(js2int(argv[1]));
break;
@ -828,11 +818,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
draw_circle(js2vec2(argv[1]), js2number(argv[2]), js2number(argv[2]), js2color(argv[3]), -1);
break;
case 117:
str = JS_ToCString(js, argv[1]);
ret = script_runfile(str);
break;
case 118:
str = JS_ToCString(js,argv[1]);
ret = bb2js(text_bb(str, js2number(argv[2]), js2number(argv[3]), 1.0));
@ -843,15 +828,10 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
ret = JS_NewInt64(js, file_mod_secs(str));
break;
case 122:
str = JS_ToCString(js, argv[1]);
ret = file_eval_env(str, argv[2]);
break;
case 123:
str = JS_ToCString(js, argv[1]);
str2 = JS_ToCString(js, argv[3]);
ret = eval_file_env(str, str2, argv[2]);
ret = eval_script_env(str, argv[2], str2);
break;
case 124:
@ -1055,7 +1035,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
ret = str2js(COM);
break;
case 257:
engine_start(argv[1]);
engine_start(argv[1], argv[2]);
break;
case 259:
@ -1994,8 +1974,8 @@ JSValue duk_performance(JSContext *js, JSValueConst this, int argc, JSValueConst
return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST));
case 7:
for (int i = 0; i < js2number(argv[2]); i++)
script_call_sym(argv[1]);
script_call_sym(argv[3]);
script_call_sym(argv[1],0,NULL);
script_call_sym(argv[3],0,NULL);
break;
}
return JS_UNDEFINED;

View file

@ -137,6 +137,12 @@ static int ls_ftw(const char *path, const struct stat *sb, int typeflag)
return 0;
}
time_t file_mod_secs(const char *file) {
struct stat attr;
stat(file, &attr);
return attr.st_mtime;
}
// TODO: Not reentrant
char **ls(const char *path)
{

View file

@ -4,6 +4,7 @@
#include <stdio.h>
#include "stb_ds.h"
#include "string.h"
#include <time.h>
extern char *DATA_PATH;
extern int LOADED_GAME;
@ -17,6 +18,7 @@ FILE *path_open(const char *tag, const char *fmt, ...);
char **ls(const char *path);
int cp(const char *p1, const char *p2);
int fexists(const char *path);
time_t file_mod_secs(const char *file);
char *dirname(const char *path);

View file

@ -1,22 +1,8 @@
#include "script.h"
#include "log.h"
#include "stdio.h"
#include "jsffi.h"
#include "font.h"
#include "gameobject.h"
#include "ftw.h"
#include "stb_ds.h"
#include "sys/stat.h"
#include "sys/types.h"
#include "time.h"
#include "resources.h"
#include "input.h"
#include <stdarg.h>
@ -29,53 +15,23 @@ JSRuntime *rt = NULL;
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP
#endif
static struct {
char *key;
JSValue value;
} *jsstrs = NULL;
JSValue jstr(const char *str)
{
int index = shgeti(jsstrs, str);
if (index != -1) return jsstrs[index].value;
JSValue v = str2js(str);
shput(jsstrs, str, v);
return v;
}
static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) {
if (typeflag != FTW_F)
return 0;
if (!strcmp(".prefab", strrchr(fpath, '.')))
script_dofile(fpath);
return 0;
}
void script_startup() {
rt = JS_NewRuntime();
js = JS_NewContext(rt);
sh_new_arena(jsstrs);
ffi_load();
for (int i = 0; i < 100; i++)
num_cache[i] = int2js(i);
script_dofile("scripts/engine.js");
// jso_file("scripts/engine.js");
size_t len;
char *eng = slurp_text("scripts/engine.js", &len);
eval_script_env("scripts/engine.js", JS_GetGlobalObject(js), eng);
free(eng);
}
void script_stop()
{
script_evalf("Event.notify('quit');");
send_signal("quit",0,NULL);
script_evalf("prosperon.quit();");
ffi_stop();
for (int i = 0; i < shlen(jsstrs); i++)
JS_FreeValue(js,jsstrs[i].value);
#if LEAK
JS_FreeContext(js);
@ -83,60 +39,7 @@ void script_stop()
#endif
}
void script_gc()
{
JS_RunGC(rt);
}
JSValue num_cache[100] = {0};
/*int js_print_exception(JSValue v) {
#ifndef NDEBUG
if (JS_IsException(v)) {
JSValue exception = JS_GetException(js);
if (JS_IsNull(exception)) {
JS_FreeValue(js,exception);
return 0;
}
JSValue val = JS_ToCStringJS_GetPropertyStr(js, exception, "stack");
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
const char *stack = JS_ToCString(js, val);
YughLog(LOG_SCRIPT, LOG_ERROR, "%s :: %s\n%s", name, msg,stack);
js_stacktrace();
JS_FreeCString(js, name);
JS_FreeCString(js, msg);
JS_FreeCString(js, stack);
JS_FreeValue(js,val);
JS_FreeValue(js,exception);
return 1;
}
#endif
return 0;
}
*/
void script_run(const char *script, const char *file) {
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS);
js_print_exception(obj);
JS_FreeValue(js,obj);
}
void script_evalf(const char *format, ...)
{
char fmtbuf[4096];
va_list args;
va_start(args, format);
vsnprintf(fmtbuf, 4096, format, args);
va_end(args);
JSValue obj = JS_Eval(js, fmtbuf, strlen(fmtbuf), "C eval", JS_EVAL_FLAGS);
js_print_exception(obj);
JS_FreeValue(js,obj);
}
void script_gc() { JS_RunGC(rt); }
uint8_t *script_compile(const char *file, size_t *len) {
size_t file_len;
@ -157,102 +60,35 @@ JSValue script_run_bytecode(uint8_t *code, size_t len)
return ret;
}
struct callee stacktrace_callee;
time_t file_mod_secs(const char *file) {
struct stat attr;
stat(file, &attr);
return attr.st_mtime;
}
void js_stacktrace() {
#ifndef NDEBUG
script_evalf("console.stack();");
#endif
}
void js_dump_stack() {
js_stacktrace();
}
int script_dofile(const char *file) {
JSValue ret = script_runfile(file);
JS_FreeValue(js,ret);
return file_mod_secs(file);
}
JSValue script_runjso(const uint8_t *buf, size_t len)
void script_evalf(const char *format, ...)
{
JSValue obj = JS_ReadObject(js, buf, len, JS_EVAL_FLAGS);
JSValue ret = JS_EvalFunction(js, obj);
js_print_exception(ret);
return ret;
}
char fmtbuf[4096];
va_list args;
va_start(args, format);
vsnprintf(fmtbuf, 4096, format, args);
va_end(args);
time_t jso_file(const char *file)
{
size_t len;
uint8_t *byte = slurp_file(file, &len);
JSValue obj = JS_ReadObject(js, byte, len, JS_READ_OBJ_BYTECODE);
JSValue ret = JS_EvalFunction(js, obj);
js_print_exception(ret);
JS_FreeValue(js,ret);
JS_FreeValue(js,obj);
free(byte);
return file_mod_secs(file);
}
JSValue script_runfile(const char *file)
{
size_t len;
char *script = slurp_text(file, &len);
if (!script) return JS_UNDEFINED;
YughWarn("Eval %s.", file);
JSValue obj = JS_Eval(js, script, len, file, JS_EVAL_FLAGS);
JSValue obj = JS_Eval(js, fmtbuf, strlen(fmtbuf), "C eval", JS_EVAL_FLAGS);
js_print_exception(obj);
free(script);
return obj;
JS_FreeValue(js,obj);
}
/* env is an object in the scripting environment;
s is the function to call on that object
*/
void script_eval_w_env(const char *s, JSValue env, const char *file) {
JSValue v = JS_EvalThis(js, env, s, strlen(s), file, JS_EVAL_FLAGS);
js_print_exception(v);
JS_FreeValue(js, v);
}
JSValue eval_file_env(const char *script, const char *file, JSValue env)
JSValue eval_script_env(const char *file, JSValue env, const char *script)
{
JSValue v = JS_EvalThis(js, env, script, strlen(script), file, JS_EVAL_FLAGS);
js_print_exception(v);
return v;
}
JSValue file_eval_env(const char *file, JSValue env)
{
size_t len;
char *script = slurp_text(file, &len);
JSValue v = JS_EvalThis(js, env, script, len, file, JS_EVAL_FLAGS);
free(script);
js_print_exception(v);
return v;
}
void script_call_sym(JSValue sym) {
void script_call_sym(JSValue sym, int argc, JSValue *argv) {
if (!JS_IsFunction(js, sym)) return;
struct callee c;
c.fn = sym;
c.obj = JS_GetGlobalObject(js);
call_callee(&c);
}
void script_call_fn_arg(JSValue fn, JSValue arg)
{
if (!JS_IsFunction(js,fn)) return;
JSValue ret = JS_Call(js, fn, JS_GetGlobalObject(js), 1, &arg);
JSValue ret = JS_Call(js, sym, JS_GetGlobalObject(js), argc, argv);
js_print_exception(ret);
JS_FreeValue(js, ret);
}
@ -266,62 +102,3 @@ void out_memusage(const char *file)
JS_DumpMemoryUsage(f, &jsmem, rt);
fclose(f);
}
JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv)
{
if (JS_IsUndefined(c->fn)) return JS_UNDEFINED;
if (JS_IsUndefined(c->obj)) return JS_UNDEFINED;
JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv);
js_print_exception(ret);
JS_FreeValue(js, ret);
return JS_UNDEFINED;
}
void call_callee(struct callee *c) {
js_callee_exec(c, 0, NULL);
}
void callee_dbl(struct callee c, double d) {
JSValue v = number2js(d);
js_callee_exec(&c, 1, &v);
JS_FreeValue(js, v);
}
void callee_int(struct callee c, int i) {
JSValue v = int2js(i);
js_callee_exec(&c, 1, &v);
JS_FreeValue(js, v);
}
void callee_vec2(struct callee c, HMM_Vec2 vec) {
JSValue v = vec22js(vec);
js_callee_exec(&c, 1, &v);
JS_FreeValue(js, v);
}
void script_callee(struct callee c, int argc, JSValue *argv) {
js_callee_exec(&c, argc, argv);
}
void free_callee(struct callee c)
{
JS_FreeValue(js,c.fn);
JS_FreeValue(js,c.obj);
}
void send_signal(const char *signal, int argc, JSValue *argv)
{
JSValue globalThis = JS_GetGlobalObject(js);
JSValue sig = JS_GetPropertyStr(js, globalThis, "Signal");
JS_FreeValue(js, globalThis);
JSValue fn = JS_GetPropertyStr(js, sig, "call");
JSValue args[argc+1];
args[0] = jstr(signal);
for (int i = 0; i < argc; i++)
args[1+i] = argv[i];
JS_FreeValue(js,JS_Call(js, fn, sig, argc+1, args));
JS_FreeValue(js, sig);
JS_FreeValue(js, fn);
}

View file

@ -6,53 +6,24 @@
extern JSContext *js;
struct callee {
JSValue fn;
JSValue obj;
};
struct phys_cbs {
JSValue begin;
JSValue bhit;
JSValue separate;
JSValue shit;
};
void script_call_fn_arg(JSValue fn, JSValue arg);
extern struct callee stacktrace_callee;
extern JSValue num_cache[100];
JSValue jstr(const char *str);
void js_stacktrace();
void script_startup();
void script_stop();
void script_run(const char *script, const char *file);
void script_evalf(const char *format, ...);
int script_dofile(const char *file);
time_t jso_file(const char *file);
JSValue script_runfile(const char *file);
JSValue eval_file_env(const char *script, const char *file, JSValue env);
void script_update(double dt);
void script_draw();
void free_callee(struct callee c);
void duk_run_err();
void js_dump_stack();
void out_memusage(const char *f);
void js_stacktrace();
void script_editor();
void script_call(const char *f);
void script_call_sym(JSValue sym);
void call_callee(struct callee *c);
void script_callee(struct callee c, int argc, JSValue *argv);
int script_has_sym(void *sym);
void script_eval_w_env(const char *s, JSValue env, const char *file);
JSValue file_eval_env(const char *file, JSValue env);
void script_evalf(const char *format, ...);
JSValue eval_script_env(const char *file, JSValue env, const char *script);
time_t file_mod_secs(const char *file);
void script_call_sym(JSValue sym, int argc, JSValue *argv);
void send_signal(const char *signal, int argc, JSValue *argv);
void script_gc();
JSValue script_run_bytecode(uint8_t *code, size_t len);

View file

@ -280,7 +280,7 @@ void sound_fillbuf(struct sound *s, soundbyte *buf, int n) {
if (s->loop)
s->frame = 0;
script_call_sym(s->hook);
script_call_sym(s->hook,0,NULL);
}
}

File diff suppressed because it is too large Load diff

View file

@ -91,6 +91,8 @@ typedef struct JSRefCountHeader {
int ref_count;
} JSRefCountHeader;
void quickjs_set_dumpout(FILE *f);
#define JS_FLOAT64_NAN NAN
#ifdef CONFIG_CHECK_JSVALUE

View file

@ -84,22 +84,24 @@ static char **args;
static JSValue c_init_fn;
static JSValue c_process_fn;
void c_init() {
mainwin.start = 1;
script_evalf("world_start();");
render_init();
window_set_icon("icons/moon.gif");
window_resize(sapp_width(), sapp_height());
particle_init();
if (!JS_IsUndefined(c_init_fn))
script_call_sym(c_init_fn);
script_call_sym(c_init_fn,0,NULL);
}
int frame_fps() { return 1.0/sapp_frame_duration(); }
static void process_frame()
{
script_call_sym(c_process_fn,0,NULL);
double elapsed = stm_sec(stm_laptime(&frame_t));
script_evalf("prosperon.appupdate(%g);", elapsed);
/* Timers all update every frame - once per monitor refresh */
@ -321,9 +323,10 @@ int main(int argc, char **argv) {
return 0;
}
void engine_start(JSValue fn)
void engine_start(JSValue fn, JSValue procfn)
{
c_init_fn = fn;
c_process_fn = procfn;
start_t = frame_t = stm_now();
physlast = updatelast = start_t;

View file

@ -11,7 +11,7 @@ void sim_stop();
void sim_step();
int phys_stepping();
void print_stacktrace();
void engine_start(JSValue fn); /* fn runs after the engine starts */
void engine_start(JSValue fn, JSValue proc_fn); /* fn runs after the engine starts */
int frame_fps();
void quit();