tests; new callbacks
This commit is contained in:
parent
7dfd8e6f9a
commit
da5b7154d7
|
@ -35,3 +35,6 @@ Computation takes place in turns. Each entity has functions called, if they exis
|
||||||
|debug|use draw functions with the object's world position, during debug pass|
|
|debug|use draw functions with the object's world position, during debug pass|
|
||||||
|gui|draw functions in screen space, during gameplay gui pass|
|
|gui|draw functions in screen space, during gameplay gui pass|
|
||||||
|draw|draw functions in world space|
|
|draw|draw functions in world space|
|
||||||
|
|
||||||
|
## Guidelines
|
||||||
|
When dealing with callbacks, callback registration can include objects or functions, but not both. You should either register an object to a list that always has 'update' called on them, or you should register the object's update function as a closure over the object.
|
|
@ -108,10 +108,6 @@ var Debug = {
|
||||||
cmd(82, obj.body);
|
cmd(82, obj.body);
|
||||||
},
|
},
|
||||||
|
|
||||||
register_call(fn, obj) {
|
|
||||||
Register.debug.register(fn,obj);
|
|
||||||
},
|
|
||||||
|
|
||||||
gameobject(go) { cmd(15, go.body); },
|
gameobject(go) { cmd(15, go.body); },
|
||||||
|
|
||||||
draw_bb: false,
|
draw_bb: false,
|
||||||
|
|
|
@ -191,7 +191,8 @@ var editor = {
|
||||||
Game.play();
|
Game.play();
|
||||||
Player.players[0].uncontrol(this);
|
Player.players[0].uncontrol(this);
|
||||||
Player.players[0].control(limited_editor);
|
Player.players[0].control(limited_editor);
|
||||||
Register.unregister_obj(this);
|
editor.cbs.forEach(cb => cb());
|
||||||
|
editor.cbs = [];
|
||||||
load("predbg.js");
|
load("predbg.js");
|
||||||
console.warn(`starting game with ${this.dbg_ur}`);
|
console.warn(`starting game with ${this.dbg_ur}`);
|
||||||
editor.dbg_play = Primum.spawn(this.dbg_ur);
|
editor.dbg_play = Primum.spawn(this.dbg_ur);
|
||||||
|
@ -205,18 +206,23 @@ var editor = {
|
||||||
Game.play();
|
Game.play();
|
||||||
Player.players[0].uncontrol(this);
|
Player.players[0].uncontrol(this);
|
||||||
Player.players[0].control(limited_editor);
|
Player.players[0].control(limited_editor);
|
||||||
Register.unregister_obj(this);
|
editor.cbs.forEach(cb=>cb());
|
||||||
|
editor.cbs = [];
|
||||||
load("game.js");
|
load("game.js");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cbs: [],
|
||||||
|
|
||||||
enter_editor() {
|
enter_editor() {
|
||||||
Game.pause();
|
Game.pause();
|
||||||
Player.players[0].control(this);
|
Player.players[0].control(this);
|
||||||
Player.players[0].uncontrol(limited_editor);
|
Player.players[0].uncontrol(limited_editor);
|
||||||
Register.gui.register(editor.gui, editor);
|
|
||||||
Register.draw.register(editor.draw, editor);
|
editor.cbs.push(Register.gui.register(editor.gui.bind(editor)));
|
||||||
Debug.register_call(editor.ed_debug, editor);
|
editor.cbs.push(Register.draw.register(editor.draw.bind(editor)));
|
||||||
Register.update.register(gui_controls.update, gui_controls);
|
editor.cbs.push(Register.debug.register(editor.ed_debug.bind(editor)));
|
||||||
|
editor.cbs.push(Register.update.register(gui_controls.update, gui_controls));
|
||||||
|
|
||||||
this.desktop = Primum.spawn(ur.arena);
|
this.desktop = Primum.spawn(ur.arena);
|
||||||
Primum.rename_obj(this.desktop.toString(), "desktop");
|
Primum.rename_obj(this.desktop.toString(), "desktop");
|
||||||
this.edit_level = this.desktop;
|
this.edit_level = this.desktop;
|
||||||
|
|
|
@ -81,7 +81,7 @@ var timer = {
|
||||||
},
|
},
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
Register.unregister_obj(this);
|
this.end();
|
||||||
this.fn = undefined;
|
this.fn = undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ var timer = {
|
||||||
t.time = secs;
|
t.time = secs;
|
||||||
t.remain = secs;
|
t.remain = secs;
|
||||||
t.fn = fn;
|
t.fn = fn;
|
||||||
Register.update.register(t.update, t);
|
t.end = Register.update.register(timer.update.bind(t));
|
||||||
return function() { t.kill(); };
|
return function() { t.kill(); };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -162,12 +162,7 @@ var Register = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
unregister_obj(obj) {
|
unregister_obj(obj) { Player.uncontrol(obj); },
|
||||||
Register.registries.forEach(function(x) {
|
|
||||||
x.unregister_obj(obj);
|
|
||||||
});
|
|
||||||
Player.uncontrol(obj);
|
|
||||||
},
|
|
||||||
|
|
||||||
endofloop(fn) {
|
endofloop(fn) {
|
||||||
if (!this.inloop)
|
if (!this.inloop)
|
||||||
|
@ -186,34 +181,18 @@ var Register = {
|
||||||
registries: [],
|
registries: [],
|
||||||
|
|
||||||
add_cb(idx, name) {
|
add_cb(idx, name) {
|
||||||
var entries = [];
|
|
||||||
var n = {};
|
var n = {};
|
||||||
|
var fns = [];
|
||||||
|
|
||||||
n.register = function(fn, obj) {
|
n.register = function(fn, obj) {
|
||||||
if (!obj) {
|
if (typeof fn !== 'function') return;
|
||||||
Log.error("Refusing to register a function without a destroying object.");
|
if (typeof obj === 'object')
|
||||||
return;
|
fn = fn.bind(obj);
|
||||||
}
|
fns.push(fn);
|
||||||
entries.push({
|
return function() { fns.remove(fn); };
|
||||||
fn: fn,
|
|
||||||
obj: obj
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
n.unregister = function(fn) {
|
|
||||||
entries = entries.filter(function(e) { return e.fn !== fn; });
|
|
||||||
}
|
|
||||||
|
|
||||||
n.unregister_obj = function(obj) {
|
|
||||||
entries = entries.filter(function(e) { return e.obj !== obj; });
|
|
||||||
}
|
|
||||||
|
|
||||||
n.broadcast = function(...args) {
|
|
||||||
entries.forEach(x => x.fn.call(x.obj, ...args));
|
|
||||||
}
|
|
||||||
|
|
||||||
n.clear = function() {
|
|
||||||
entries = [];
|
|
||||||
}
|
}
|
||||||
|
n.broadcast = function(...args) { fns.forEach(x => x(...args)); }
|
||||||
|
n.clear = function() { fns = []; }
|
||||||
|
|
||||||
register(idx, n.broadcast, n);
|
register(idx, n.broadcast, n);
|
||||||
|
|
||||||
|
|
|
@ -416,14 +416,19 @@ var gameobject = {
|
||||||
this.sync();
|
this.sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
unregister() {
|
||||||
|
this.timers.forEach(t=>t());
|
||||||
|
this.timers = [];
|
||||||
|
},
|
||||||
|
|
||||||
check_registers(obj) {
|
check_registers(obj) {
|
||||||
Register.unregister_obj(obj);
|
obj.unregister();
|
||||||
|
|
||||||
if (typeof obj.update === 'function')
|
if (typeof obj.update === 'function')
|
||||||
Register.update.register(obj.update, obj);
|
obj.timers.push(Register.update.register(obj.update.bind(obj)));
|
||||||
|
|
||||||
if (typeof obj.physupdate === 'function')
|
if (typeof obj.physupdate === 'function')
|
||||||
Register.physupdate.register(obj.physupdate, obj);
|
obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj)));
|
||||||
|
|
||||||
if (typeof obj.collide === 'function')
|
if (typeof obj.collide === 'function')
|
||||||
obj.register_hit(obj.collide, obj);
|
obj.register_hit(obj.collide, obj);
|
||||||
|
@ -432,13 +437,13 @@ var gameobject = {
|
||||||
obj.register_separate(obj.separate, obj);
|
obj.register_separate(obj.separate, obj);
|
||||||
|
|
||||||
if (typeof obj.draw === 'function')
|
if (typeof obj.draw === 'function')
|
||||||
Register.draw.register(obj.draw,obj);
|
obj.timers.push(Register.draw.register(obj.draw.bind(obj)));
|
||||||
|
|
||||||
if (typeof obj.debug === 'function')
|
if (typeof obj.debug === 'function')
|
||||||
Register.debug.register(obj.debug, obj);
|
obj.timers.push(Register.debug.register(obj.debug.bind(obj)));
|
||||||
|
|
||||||
if (typeof obj.gui === 'function')
|
if (typeof obj.gui === 'function')
|
||||||
Register.gui.register(obj.gui,obj);
|
obj.timers.push(Register.gui.register(obj.gui.bind(obj)));
|
||||||
|
|
||||||
for (var k in obj) {
|
for (var k in obj) {
|
||||||
if (!k.startswith("on_")) continue;
|
if (!k.startswith("on_")) continue;
|
||||||
|
@ -560,7 +565,7 @@ var gameobject = {
|
||||||
this.__kill = true;
|
this.__kill = true;
|
||||||
|
|
||||||
this.timers.forEach(t => t());
|
this.timers.forEach(t => t());
|
||||||
this.timers = undefined;
|
this.timers = [];
|
||||||
|
|
||||||
if (this.level) {
|
if (this.level) {
|
||||||
this.level.remove_obj(this);
|
this.level.remove_obj(this);
|
||||||
|
@ -568,13 +573,11 @@ var gameobject = {
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.do_uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
|
||||||
|
|
||||||
if (this.__proto__.instances)
|
if (this.__proto__.instances)
|
||||||
this.__proto__.instances.remove(this);
|
this.__proto__.instances.remove(this);
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
Register.unregister_obj(this.components[key]);
|
|
||||||
this.components[key].kill();
|
this.components[key].kill();
|
||||||
this.components[key].gameobject = undefined;
|
this.components[key].gameobject = undefined;
|
||||||
delete this.components[key];
|
delete this.components[key];
|
||||||
|
|
|
@ -173,7 +173,7 @@ var Tween = {
|
||||||
|
|
||||||
defn.play = function() {
|
defn.play = function() {
|
||||||
if (playing) return;
|
if (playing) return;
|
||||||
Register.update.register(defn.fn, defn);
|
defn._end = Register.update.register(defn.fn.bind(defn));
|
||||||
playing = true;
|
playing = true;
|
||||||
};
|
};
|
||||||
defn.restart = function() {
|
defn.restart = function() {
|
||||||
|
@ -185,7 +185,7 @@ var Tween = {
|
||||||
};
|
};
|
||||||
defn.stop = function() { if (!playing) return; defn.pause(); defn.restart(); };
|
defn.stop = function() { if (!playing) return; defn.pause(); defn.restart(); };
|
||||||
defn.pause = function() {
|
defn.pause = function() {
|
||||||
Register.update.unregister(defn.fn);
|
defn._end();
|
||||||
if (!playing) return;
|
if (!playing) return;
|
||||||
|
|
||||||
playing = false;
|
playing = false;
|
||||||
|
|
|
@ -625,9 +625,9 @@ static cpBool handle_collision(cpArbiter *arb, int type) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CTYPE_SEP:
|
case CTYPE_SEP:
|
||||||
/* if (JS_IsObject(go->cbs.separate.obj))
|
if (JS_IsObject(go->cbs.separate.obj))
|
||||||
duk_call_phys_cb(norm1, go->cbs.separate, go2, arb);
|
duk_call_phys_cb(norm1, go->cbs.separate, go2, arb);
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1478,11 +1478,9 @@ JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
// unregister_obj(obj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
// unregister_gui(c);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
|
|
|
@ -155,6 +155,7 @@ static struct par_vert pv[MAX_PARTICLES];
|
||||||
void parallel_pv(emitter *e, struct scheduler *sched, struct sched_task_partition t, sched_uint thread_num)
|
void parallel_pv(emitter *e, struct scheduler *sched, struct sched_task_partition t, sched_uint thread_num)
|
||||||
{
|
{
|
||||||
for (int i=t.start; i < t.end; i++) {
|
for (int i=t.start; i < t.end; i++) {
|
||||||
|
if (e->particles[i].life <= 0) continue;
|
||||||
particle *p = &e->particles[i];
|
particle *p = &e->particles[i];
|
||||||
pv[i].pos = p->pos.xy;
|
pv[i].pos = p->pos.xy;
|
||||||
pv[i].angle = p->angle;
|
pv[i].angle = p->angle;
|
||||||
|
@ -172,7 +173,7 @@ void emitters_draw()
|
||||||
par_bind.fs.images[0] = e->texture->id;
|
par_bind.fs.images[0] = e->texture->id;
|
||||||
|
|
||||||
struct sched_task task;
|
struct sched_task task;
|
||||||
scheduler_add(&sched, &task, parallel_pv, e, arrlen(e->particles), arrlen(e->particles)/SCHED_DEFAULT);
|
scheduler_add(&sched, &task, parallel_pv, e, arrlen(e->particles), arrlen(e->particles)/sched.threads_num);
|
||||||
scheduler_join(&sched, &task);
|
scheduler_join(&sched, &task);
|
||||||
|
|
||||||
sg_append_buffer(par_bind.vertex_buffers[0], &(sg_range){.ptr=&pv, .size=sizeof(struct par_vert)*arrlen(e->particles)});
|
sg_append_buffer(par_bind.vertex_buffers[0], &(sg_range){.ptr=&pv, .size=sizeof(struct par_vert)*arrlen(e->particles)});
|
||||||
|
@ -191,6 +192,7 @@ static HMM_Vec4 g_accel;
|
||||||
void parallel_step(emitter *e, struct scheduler *shed, struct sched_task_partition t, sched_uint thread_num)
|
void parallel_step(emitter *e, struct scheduler *shed, struct sched_task_partition t, sched_uint thread_num)
|
||||||
{
|
{
|
||||||
for (int i = t.end-1; i >=0; i--) {
|
for (int i = t.end-1; i >=0; i--) {
|
||||||
|
if (e->particles[i].life <= 0) continue;
|
||||||
if (e->gravity)
|
if (e->gravity)
|
||||||
e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel);
|
e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel);
|
||||||
e->particles[i].v = HMM_AddV4(e->particles[i].v, HMM_MulV4F((HMM_Vec4){frand(2)-1, frand(2)-1, 0,0}, 1000*dt));
|
e->particles[i].v = HMM_AddV4(e->particles[i].v, HMM_MulV4F((HMM_Vec4){frand(2)-1, frand(2)-1, 0,0}, 1000*dt));
|
||||||
|
@ -200,10 +202,10 @@ void parallel_step(emitter *e, struct scheduler *shed, struct sched_task_partiti
|
||||||
e->particles[i].color = sample_sampler(&e->color, (e->life-e->particles[i].life)/e->life);
|
e->particles[i].color = sample_sampler(&e->color, (e->life-e->particles[i].life)/e->life);
|
||||||
e->particles[i].scale = e->scale;
|
e->particles[i].scale = e->scale;
|
||||||
|
|
||||||
if (e->particles[i].life <= 0)
|
// if (e->particles[i].life <= 0)
|
||||||
arrdelswap(e->particles, i);
|
// arrdelswap(e->particles, i);
|
||||||
else if (query_point(e->particles[i].pos.xy))
|
// else if (query_point(e->particles[i].pos.xy))
|
||||||
arrdelswap(e->particles,i);
|
// arrdelswap(e->particles,i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +214,7 @@ void emitter_step(emitter *e, double mdt) {
|
||||||
g_accel = HMM_MulV4F((HMM_Vec4){cpSpaceGetGravity(space).x, cpSpaceGetGravity(space).y, 0, 0}, dt);
|
g_accel = HMM_MulV4F((HMM_Vec4){cpSpaceGetGravity(space).x, cpSpaceGetGravity(space).y, 0, 0}, dt);
|
||||||
if (arrlen(e->particles) == 0) return;
|
if (arrlen(e->particles) == 0) return;
|
||||||
struct sched_task task;
|
struct sched_task task;
|
||||||
scheduler_add(&sched, &task, parallel_step, e, arrlen(e->particles), arrlen(e->particles));
|
scheduler_add(&sched, &task, parallel_step, e, arrlen(e->particles), arrlen(e->particles)/sched.threads_num);
|
||||||
scheduler_join(&sched, &task);
|
scheduler_join(&sched, &task);
|
||||||
|
|
||||||
if (!e->on) return;
|
if (!e->on) return;
|
||||||
|
|
40
tests/bind_v_call.js
Normal file
40
tests/bind_v_call.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
var binds = [];
|
||||||
|
var cbs = [];
|
||||||
|
var fats = [];
|
||||||
|
var count = 1000000;
|
||||||
|
|
||||||
|
var a = {
|
||||||
|
n: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_a() {
|
||||||
|
this.n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
binds.push(test_a.bind(a));
|
||||||
|
console.log(`Make bind time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
fats.push(() => test_a.call(a));
|
||||||
|
console.log(`Make fat time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
binds[i]();
|
||||||
|
}
|
||||||
|
console.log(`Bind time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
fats[i]();
|
||||||
|
}
|
||||||
|
console.log(`Fat time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
test_a.call(a);
|
||||||
|
|
||||||
|
console.log(`Call time: ${Date.now()-start} ms`);
|
24
tests/bind_v_fn.js
Normal file
24
tests/bind_v_fn.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
var binds = [];
|
||||||
|
var a = {
|
||||||
|
n: 1,
|
||||||
|
test() { this.n++; }
|
||||||
|
};
|
||||||
|
var count = 10000000;
|
||||||
|
|
||||||
|
var start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
binds.push(a.test.bind(a));
|
||||||
|
|
||||||
|
console.log(`Make bind time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
binds[i]();
|
||||||
|
|
||||||
|
console.log(`Bind time: ${Date.now()-start} ms`);
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
a['test']();
|
||||||
|
|
||||||
|
console.log(`Call time: ${Date.now()-start} ms`);
|
Loading…
Reference in a new issue