From 3f73a808d8d9fedf9525024246ec214d81279202 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 2 Apr 2024 07:41:46 -0500 Subject: [PATCH] Fix animations from not deleting gameobjects --- scripts/actor.js | 8 ++++---- scripts/components.js | 30 ++++++++++++++---------------- scripts/entity.js | 36 +++++++++++++++++++----------------- scripts/std.js | 1 + source/engine/debug/log.c | 1 - source/engine/jsffi.c | 33 ++++++++++++--------------------- source/engine/jsffi.h | 7 ++++++- source/engine/sprite.c | 4 +++- source/engine/yugine.c | 5 ++++- 9 files changed, 63 insertions(+), 62 deletions(-) diff --git a/scripts/actor.js b/scripts/actor.js index 7d93124..d6d04b7 100644 --- a/scripts/actor.js +++ b/scripts/actor.js @@ -58,14 +58,14 @@ actor.interval = function(fn, seconds) { } actor.delay = function(fn, seconds) { - var that = this; + var timers = this.timers; var stop = function() { - that.timers.remove(stop); + timers.remove(stop); rm(); } function execute() { - fn.call(that); + fn(); stop(); } @@ -80,7 +80,7 @@ actor.delay = function(fn, seconds) { var rm = Register.appupdate.register(update); - this.timers.push(stop); + timers.push(stop); return stop; }; diff --git a/scripts/components.js b/scripts/components.js index 84fdeb1..ee70e35 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -89,33 +89,33 @@ Object.mixin(os.sprite(true), { anim:{}, playing: 0, play(str) { - console.trace(); this.del_anim?.(); - var sp = this; + var self = this; var stop; - this.del_anim = function() { - sp = undefined; + self.del_anim = function() { + self.del_anim = undefined; + self = undefined; advance = undefined; - this.del_anim = undefined; stop(); } str ??= 0; - var playing = this.anim[str]; + var playing = self.anim[str]; if (!playing) return; var f = 0; - sp.path = playing.path; + self.path = playing.path; function advance() { - if (!sp) this.del_anim(); - if (!sp.gameobject) return; - //sp.path = playing.path; - sp.frame = playing.frames[f].rect; + if (!self) return; + if (!self.gameobject) return; + //self.path = playing.path; + self.frame = playing.frames[f].rect; f = (f+1)%playing.frames.length; if (f === 0) { - sp.anim_done?.(); - if (!sp.loop) { sp.stop(); return; } + self.anim_done?.(); + self.anim_done = undefined; +// if (!self.loop) { self.stop(); return; } } - stop = sp.gameobject.delay(advance, playing.frames[f].time); + stop = self.gameobject.delay(advance, playing.frames[f].time); } this.tex(game.texture(playing.path)); advance(); @@ -124,7 +124,6 @@ Object.mixin(os.sprite(true), { this.del_anim?.(); }, set path(p) { - console.info(`setting path to ${p}`); p = Resources.find_image(p); if (!p) { console.warn(`Could not find image ${p}.`); @@ -347,7 +346,6 @@ var SpriteAnim = { find(path) { if (!io.exists(path + ".asset")) return; var asset = JSON.parse(io.slurp(path + ".asset")); - }, }; diff --git a/scripts/entity.js b/scripts/entity.js index 2ff0b79..d245d15 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -180,10 +180,9 @@ var gameobject = { }, delay(fn, seconds) { - var that = this; - + var timers = this.timers; var stop = function() { - that.timers.remove(stop); + timers.remove(stop); execute = undefined; stop = undefined; rm?.(); @@ -192,7 +191,7 @@ var gameobject = { } function execute() { - fn.call(that); + fn(); stop?.(); } @@ -205,7 +204,7 @@ var gameobject = { } var rm = Register.update.register(update); - this.timers.push(stop); + timers.push(stop); return stop; }, @@ -256,20 +255,20 @@ var gameobject = { spawn(text, config, callback) { var ent = os.make_gameobject(); ent.setref(ent); - ent.components ??= {}; - ent.objects ??= {}; + ent.components = {}; + ent.objects = {}; ent.timers = []; if (typeof text === 'object') // assume it's an ur { config = text.data; text = text.text; } - + if (text) use(text, ent); if (config) Object.assign(ent, json.decode(io.slurp(config))); - + ent.reparent(this); ent._ed = { @@ -301,8 +300,6 @@ var gameobject = { if (sim.playing()) if (typeof ent.start === 'function') ent.start(); - ent.objects ??= {}; - ent.components ??= {}; Object.hide(ent, 'ur', 'components', 'objects', '_ed', 'timers', 'master'); var mur = ent.get_ur(); @@ -310,16 +307,17 @@ var gameobject = { mur.proto = json.decode(json.encode(ent)); ent.sync(); - + if (!Object.empty(ent.objects)) { var o = ent.objects; delete ent.objects; for (var i in o) { - say(`MAKING ${i}`); + console.info(`MAKING ${i}`); var n = ent.spawn(ur[o[i].ur]); ent.rename_obj(n.toString(), i); delete o[i].ur; Object.assign(n, o[i]); + n.sync(); } } @@ -537,14 +535,19 @@ var gameobject = { for (var key in this.components) { this.components[key].kill?.(); this.components[key].gameobject = undefined; + this[key].enabled = false; delete this.components[key]; delete this[key]; } + delete this.components; this.clear(); - this.objects = undefined; - if (typeof this.stop === 'function') this.stop(); + + for (var i in this) { + if (typeof this[i] === 'object') delete this[i]; + if (typeof this[i] === 'function') delete this[i]; + } }, up() { return [0, 1].rotate(this.angle); }, @@ -581,7 +584,6 @@ var gameobject = { }, add_component(comp, data, name) { - data ??= undefined; if (typeof comp.make !== 'function') return; name ??= comp.toString(); name = obj_unique_name(name, this); @@ -607,7 +609,7 @@ function go_init() { gop.sync = function() { gsync.call(this); this.components.forEach(function(x) { x.sync?.(); }); - this.objects.forEach(function(x) { x.sync(); }); + this.objects.forEach(function(x) { x.sync?.(); }); } } diff --git a/scripts/std.js b/scripts/std.js index fe4e6fe..83c9ac4 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -11,6 +11,7 @@ appy.inputs = {}; if (os.sys() === 'macos') { appy.inputs['S-q'] = os.quit; appy.inputs['S-h'] = function() { }; + appy.inputs['S-g'] = os.gc; } player[0].control(appy); diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 16a5505..ba58fc9 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -87,7 +87,6 @@ void mYughLog(int category, int priority, int line, const char *file, const char vprintf(message, args); va_end(args); printf("\n"); - fflush(stdout); } //if (priority >= LOG_ERROR) diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 0c14080..cd65a94 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -43,9 +43,18 @@ static JSValue globalThis; static JSClassID js_ptr_id; static JSClassDef js_ptr_class = { "POINTER" }; -JSValue str2js(const char *c) { +JSValue str2js(const char *c, ...) { if (!c) return JS_UNDEFINED; - return JS_NewString(js, c); + char *result = NULL; + va_list args; + va_start(args, c); + va_list args2; + va_copy(args2,args); + char buf[1+vsnprintf(NULL, 0, c, args)]; + va_end(args); + vsnprintf(buf, sizeof buf, c, args2); + va_end(args2); + return JS_NewString(js, buf); } const char *js2str(JSValue v) { @@ -67,25 +76,7 @@ QJSCLASS(material) QJSCLASS(mesh) QJSCLASS(window) QJSCLASS(drawmodel) - -/* qjs class colliders and constraints */ -/* constraint works for all constraints - 2d or 3d */ -static JSClassID js_constraint_id; -static void js_constraint_finalizer(JSRuntime *rt, JSValue val) { - constraint *c = JS_GetOpaque(val, js_constraint_id); - constraint_free(c); -} -static JSClassDef js_constraint_class = { - "constraint", - .finalizer = js_constraint_finalizer -}; -static constraint *js2constraint(JSValue val) { return JS_GetOpaque(val, js_constraint_id); } -static JSValue constraint2js(constraint *c) -{ - JSValue j = JS_NewObjectClass(js, js_constraint_id); - JS_SetOpaque(j, c); - return j; -} +QJSCLASS(constraint) static JSValue sound_proto; sound *js2sound(JSValue v) { return js2dsp_node(v)->data; } diff --git a/source/engine/jsffi.h b/source/engine/jsffi.h index 0593d24..e8be117 100644 --- a/source/engine/jsffi.h +++ b/source/engine/jsffi.h @@ -3,6 +3,7 @@ #include "quickjs/quickjs.h" #include "HandmadeMath.h" +#include #define MIST_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } @@ -93,6 +94,8 @@ static JSValue TYPE##2js(TYPE *n) { \ YughSpam("Created " #TYPE " at %p", n); \ JS_SetOpaque(j,n);\ return j; }\ +\ +static JSValue js_##TYPE##_memid (JSContext *js, JSValue this) { return str2js("%p", js2##TYPE(this)); } \ #define QJSGLOBALCLASS(NAME) \ JSValue NAME = JS_NewObject(js); \ @@ -108,8 +111,10 @@ JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\ QJSCLASSPREP(TYPE); \ JSValue TYPE##_proto = JS_NewObject(js); \ JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \ +JS_SetPropertyStr(js, TYPE##_proto, "memid", JS_NewCFunction(js, &js_##TYPE##_memid, "memid", 0)); \ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ + #define countof(x) (sizeof(x)/sizeof((x)[0])) void ffi_load(); @@ -125,7 +130,7 @@ int js_print_exception(JSValue v); struct rgba js2color(JSValue v); double js2number(JSValue v); JSValue number2js(double g); -JSValue str2js(const char *c); +JSValue str2js(const char *c, ...); void nota_int(char *blob); diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 5c53cc1..cfcd6d0 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -98,8 +98,10 @@ void sprite_draw_all() { qsort(sprites, arrlen(sprites), sizeof(*sprites), sprite_sort); - for (int i = 0; i < arrlen(sprites); i++) + for (int i = 0; i < arrlen(sprites); i++) { + if (!sprites[i]->enabled) continue; sprite_draw(sprites[i]); + } } void sprite_initialize() { diff --git a/source/engine/yugine.c b/source/engine/yugine.c index e77056e..2ff5b9a 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -65,7 +65,10 @@ void c_init() { JS_FreeValue(js, c_start); } -void c_frame() { script_call_sym(c_process_fn,0,NULL); } +void c_frame() { + script_call_sym(c_process_fn,0,NULL); + fflush(stdout); +} void cleanup() {