tests; new callbacks
This commit is contained in:
parent
7dfd8e6f9a
commit
da5b7154d7
|
@ -34,4 +34,7 @@ Computation takes place in turns. Each entity has functions called, if they exis
|
|||
|stop|called when the object is killed|
|
||||
|debug|use draw functions with the object's world position, during debug 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);
|
||||
},
|
||||
|
||||
register_call(fn, obj) {
|
||||
Register.debug.register(fn,obj);
|
||||
},
|
||||
|
||||
gameobject(go) { cmd(15, go.body); },
|
||||
|
||||
draw_bb: false,
|
||||
|
|
|
@ -191,7 +191,8 @@ var editor = {
|
|||
Game.play();
|
||||
Player.players[0].uncontrol(this);
|
||||
Player.players[0].control(limited_editor);
|
||||
Register.unregister_obj(this);
|
||||
editor.cbs.forEach(cb => cb());
|
||||
editor.cbs = [];
|
||||
load("predbg.js");
|
||||
console.warn(`starting game with ${this.dbg_ur}`);
|
||||
editor.dbg_play = Primum.spawn(this.dbg_ur);
|
||||
|
@ -205,18 +206,23 @@ var editor = {
|
|||
Game.play();
|
||||
Player.players[0].uncontrol(this);
|
||||
Player.players[0].control(limited_editor);
|
||||
Register.unregister_obj(this);
|
||||
editor.cbs.forEach(cb=>cb());
|
||||
editor.cbs = [];
|
||||
load("game.js");
|
||||
},
|
||||
|
||||
cbs: [],
|
||||
|
||||
enter_editor() {
|
||||
Game.pause();
|
||||
Player.players[0].control(this);
|
||||
Player.players[0].uncontrol(limited_editor);
|
||||
Register.gui.register(editor.gui, editor);
|
||||
Register.draw.register(editor.draw, editor);
|
||||
Debug.register_call(editor.ed_debug, editor);
|
||||
Register.update.register(gui_controls.update, gui_controls);
|
||||
|
||||
editor.cbs.push(Register.gui.register(editor.gui.bind(editor)));
|
||||
editor.cbs.push(Register.draw.register(editor.draw.bind(editor)));
|
||||
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);
|
||||
Primum.rename_obj(this.desktop.toString(), "desktop");
|
||||
this.edit_level = this.desktop;
|
||||
|
|
|
@ -81,7 +81,7 @@ var timer = {
|
|||
},
|
||||
|
||||
kill() {
|
||||
Register.unregister_obj(this);
|
||||
this.end();
|
||||
this.fn = undefined;
|
||||
},
|
||||
|
||||
|
@ -90,7 +90,7 @@ var timer = {
|
|||
t.time = secs;
|
||||
t.remain = secs;
|
||||
t.fn = fn;
|
||||
Register.update.register(t.update, t);
|
||||
t.end = Register.update.register(timer.update.bind(t));
|
||||
return function() { t.kill(); };
|
||||
},
|
||||
};
|
||||
|
@ -162,12 +162,7 @@ var Register = {
|
|||
});
|
||||
},
|
||||
|
||||
unregister_obj(obj) {
|
||||
Register.registries.forEach(function(x) {
|
||||
x.unregister_obj(obj);
|
||||
});
|
||||
Player.uncontrol(obj);
|
||||
},
|
||||
unregister_obj(obj) { Player.uncontrol(obj); },
|
||||
|
||||
endofloop(fn) {
|
||||
if (!this.inloop)
|
||||
|
@ -186,34 +181,18 @@ var Register = {
|
|||
registries: [],
|
||||
|
||||
add_cb(idx, name) {
|
||||
var entries = [];
|
||||
var n = {};
|
||||
var fns = [];
|
||||
|
||||
n.register = function(fn, obj) {
|
||||
if (!obj) {
|
||||
Log.error("Refusing to register a function without a destroying object.");
|
||||
return;
|
||||
}
|
||||
entries.push({
|
||||
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 = [];
|
||||
if (typeof fn !== 'function') return;
|
||||
if (typeof obj === 'object')
|
||||
fn = fn.bind(obj);
|
||||
fns.push(fn);
|
||||
return function() { fns.remove(fn); };
|
||||
}
|
||||
n.broadcast = function(...args) { fns.forEach(x => x(...args)); }
|
||||
n.clear = function() { fns = []; }
|
||||
|
||||
register(idx, n.broadcast, n);
|
||||
|
||||
|
|
|
@ -416,14 +416,19 @@ var gameobject = {
|
|||
this.sync();
|
||||
},
|
||||
|
||||
unregister() {
|
||||
this.timers.forEach(t=>t());
|
||||
this.timers = [];
|
||||
},
|
||||
|
||||
check_registers(obj) {
|
||||
Register.unregister_obj(obj);
|
||||
obj.unregister();
|
||||
|
||||
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')
|
||||
Register.physupdate.register(obj.physupdate, obj);
|
||||
obj.timers.push(Register.physupdate.register(obj.physupdate.bind(obj)));
|
||||
|
||||
if (typeof obj.collide === 'function')
|
||||
obj.register_hit(obj.collide, obj);
|
||||
|
@ -432,13 +437,13 @@ var gameobject = {
|
|||
obj.register_separate(obj.separate, obj);
|
||||
|
||||
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')
|
||||
Register.debug.register(obj.debug, obj);
|
||||
obj.timers.push(Register.debug.register(obj.debug.bind(obj)));
|
||||
|
||||
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) {
|
||||
if (!k.startswith("on_")) continue;
|
||||
|
@ -560,7 +565,7 @@ var gameobject = {
|
|||
this.__kill = true;
|
||||
|
||||
this.timers.forEach(t => t());
|
||||
this.timers = undefined;
|
||||
this.timers = [];
|
||||
|
||||
if (this.level) {
|
||||
this.level.remove_obj(this);
|
||||
|
@ -568,13 +573,11 @@ var gameobject = {
|
|||
}
|
||||
|
||||
Player.do_uncontrol(this);
|
||||
Register.unregister_obj(this);
|
||||
|
||||
if (this.__proto__.instances)
|
||||
this.__proto__.instances.remove(this);
|
||||
|
||||
for (var key in this.components) {
|
||||
Register.unregister_obj(this.components[key]);
|
||||
this.components[key].kill();
|
||||
this.components[key].gameobject = undefined;
|
||||
delete this.components[key];
|
||||
|
|
|
@ -173,7 +173,7 @@ var Tween = {
|
|||
|
||||
defn.play = function() {
|
||||
if (playing) return;
|
||||
Register.update.register(defn.fn, defn);
|
||||
defn._end = Register.update.register(defn.fn.bind(defn));
|
||||
playing = true;
|
||||
};
|
||||
defn.restart = function() {
|
||||
|
@ -185,7 +185,7 @@ var Tween = {
|
|||
};
|
||||
defn.stop = function() { if (!playing) return; defn.pause(); defn.restart(); };
|
||||
defn.pause = function() {
|
||||
Register.update.unregister(defn.fn);
|
||||
defn._end();
|
||||
if (!playing) return;
|
||||
|
||||
playing = false;
|
||||
|
|
|
@ -625,9 +625,9 @@ static cpBool handle_collision(cpArbiter *arb, int type) {
|
|||
break;
|
||||
|
||||
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);
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1478,11 +1478,9 @@ JSValue duk_register(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
break;
|
||||
|
||||
case 4:
|
||||
// unregister_obj(obj);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// unregister_gui(c);
|
||||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
for (int i=t.start; i < t.end; i++) {
|
||||
if (e->particles[i].life <= 0) continue;
|
||||
particle *p = &e->particles[i];
|
||||
pv[i].pos = p->pos.xy;
|
||||
pv[i].angle = p->angle;
|
||||
|
@ -172,7 +173,7 @@ void emitters_draw()
|
|||
par_bind.fs.images[0] = e->texture->id;
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
for (int i = t.end-1; i >=0; i--) {
|
||||
if (e->particles[i].life <= 0) continue;
|
||||
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, 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].scale = e->scale;
|
||||
|
||||
if (e->particles[i].life <= 0)
|
||||
arrdelswap(e->particles, i);
|
||||
else if (query_point(e->particles[i].pos.xy))
|
||||
arrdelswap(e->particles,i);
|
||||
// if (e->particles[i].life <= 0)
|
||||
// arrdelswap(e->particles, i);
|
||||
// else if (query_point(e->particles[i].pos.xy))
|
||||
// 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);
|
||||
if (arrlen(e->particles) == 0) return;
|
||||
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);
|
||||
|
||||
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