prosperon/scripts/debug.js

317 lines
7.4 KiB
JavaScript
Raw Normal View History

var Debug = {
2023-12-13 19:53:09 -06:00
fn_break(fn, obj) {
if (typeof fn !== 'function') return;
obj ??= globalThis;
var newfn = function() {
console.log("broke");
fn();
};
obj[fn.name] = newfn;
},
2023-05-16 13:31:19 -05:00
draw_grid(width, span, color) {
color = color ? color : Color.green;
cmd(47, width, span, color);
},
2023-12-15 12:45:09 -06:00
coordinate(pos, size, color) { GUI.text(JSON.stringify(pos.map(p=>Math.round(p))), pos, size, color); },
2023-06-06 15:49:55 -05:00
boundingbox(bb, color) {
2023-08-14 17:20:30 -05:00
color ??= Color.white;
cmd_points(0, bbox.topoints(bb), color);
2023-06-06 15:49:55 -05:00
},
2023-12-18 06:45:27 -06:00
numbered_point(pos, n, color) {
color ??= Color.white;
2024-02-25 17:31:48 -06:00
render.point(pos, 3, color);
2023-12-18 06:45:27 -06:00
GUI.text(n, pos.add([0,4]), 1, color);
},
phys_drawing: false,
draw_phys(on) {
this.phys_drawing = on;
cmd(4, this.phys_drawing);
},
draw_obj_phys(obj) {
cmd(82, obj.body);
},
2023-12-18 06:45:27 -06:00
gameobject(go) { cmd(15, go.body); },
2023-08-17 20:13:17 -05:00
draw_bb: false,
draw_gizmos: false,
draw_names: false,
draw() {
if (this.draw_bb)
2023-11-29 12:40:13 -06:00
Game.all_objects(function(x) { Debug.boundingbox(x.boundingbox(), Color.Debug.boundingbox.alpha(0.05)); });
2023-08-17 20:13:17 -05:00
2024-03-15 11:21:36 -05:00
if (sim.paused()) GUI.text("PAUSED", [0,0],1);
2023-08-17 20:13:17 -05:00
if (this.draw_gizmos)
2023-11-29 12:40:13 -06:00
Game.all_objects(function(x) {
2023-08-17 20:13:17 -05:00
if (!x.icon) return;
2024-02-25 17:31:48 -06:00
GUI.image(x.icon, Window.world2screen(x.pos));
2023-08-17 20:13:17 -05:00
});
if (this.draw_names)
2023-11-29 12:40:13 -06:00
Game.all_objects(function(x) {
2024-02-25 17:31:48 -06:00
GUI.text(x, Window.world2screen(x.pos).add([0,32]), 1, Color.Debug.names);
2023-08-17 20:13:17 -05:00
});
if (Debug.Options.gif.rec) {
2023-10-26 11:48:02 -05:00
GUI.text("REC", [0,40], 1);
GUI.text(time.timecode(time.timenow() - Debug.Options.gif.start_time, Debug.Options.gif.fps), [0,30], 1);
}
2023-09-12 00:02:57 -05:00
2024-03-15 11:21:36 -05:00
GUI.text(sim.playing() ? "PLAYING"
: sim.stepping() ?
"STEP" :
2024-03-15 11:21:36 -05:00
sim.paused() ?
"PAUSED; EDITING" :
"EDIT", [0, 0], 1);
2023-08-17 20:13:17 -05:00
},
};
function assert(op, str)
2023-12-18 17:12:05 -06:00
{
str ??= `assertion failed [value '${op}']`;
2024-03-13 16:30:55 -05:00
if (!op) {
console.error(`Assertion failed: ${str}`);
2024-03-15 11:21:36 -05:00
os.quit();
2024-03-13 16:30:55 -05:00
}
2023-12-18 17:12:05 -06:00
}
2023-08-17 20:13:17 -05:00
Debug.Options = { };
Debug.Options.Color = {
//set trigger(x) { cmd(17,x); },
//set debug(x) { cmd(16, x); },
};
var Gizmos = {
pick_gameobject_points(worldpos, gameobject, points) {
2023-11-29 17:31:41 -06:00
var idx = Math.grab_from_points(worldpos, points.map(gameobject.this2world,gameobject), 25);
2023-12-18 06:45:27 -06:00
if (idx === -1) return undefined;
return idx;
},
};
Object.assign(profile, {
best_t(t) {
2023-12-18 06:45:27 -06:00
var qq = 'ns';
if (t > 1000) {
t /= 1000;
2023-12-18 06:45:27 -06:00
qq = 'us';
if (t > 1000) {
t /= 1000;
2023-12-18 06:45:27 -06:00
qq = 'ms';
}
}
return `${t.toPrecision(4)} ${qq}`;
2023-12-18 06:45:27 -06:00
},
2023-09-11 02:46:12 -05:00
cpu(fn, times, q) {
2023-06-07 08:41:09 -05:00
times ??= 1;
2023-12-18 06:45:27 -06:00
q ??= "unnamed";
var start = profile.now();
2023-06-07 08:41:09 -05:00
for (var i = 0; i < times; i++)
fn();
2023-12-18 06:45:27 -06:00
var elapsed = profile.now() - start;
var avgt = profile.best_t(elapsed/times);
var totalt = profile.best_t(elapsed);
say(`profile [${q}]: ${profile.best_t(avgt)} average [${profile.best_t(totalt)} for ${times} loops]`);
},
2023-12-18 06:45:27 -06:00
time(fn) {
var start = profile.now();
fn();
return profile.lap(start);
2023-06-07 08:41:09 -05:00
},
2023-08-17 20:13:17 -05:00
lap(t) {
return profile.best_t(profile.now()-t);
},
2024-03-01 11:45:06 -06:00
measure(fn, str) {
str ??= 'unnamed';
var start = profile.now();
2024-03-01 11:45:06 -06:00
fn();
say(`profile [${str}]: ${profile.lap(start)}`);
2024-03-01 11:45:06 -06:00
},
2024-03-15 11:21:36 -05:00
secs() { return this.now()/1000000000; },
2024-02-25 17:31:48 -06:00
});
2024-03-01 11:45:06 -06:00
performance.test = {
barecall() { performance(0); },
unpack_num(n) { performance(1,n); },
unpack_array(n) { performance(2,n); },
pack_num() { performance(3); },
pack_string() { performance(6); },
unpack_string(s) { performance(4,s); },
unpack_32farr(a) { performance(5,a); },
call_fn_n(fn1, n) { performance(7,fn1,n,fn2); },
2023-12-18 06:45:27 -06:00
};
2024-03-01 11:45:06 -06:00
performance.test.call_fn_n.doc = "Calls fn1 n times, and then fn2.";
2024-01-14 10:24:31 -06:00
//performance.cpu.doc = `Output the time it takes to do a given function n number of times. Provide 'q' as "ns", "us", or "ms" to output the time taken in the requested resolution.`;
/* These controls are available during editing, and during play of debug builds */
Debug.inputs = {};
Debug.inputs.f1 = function () { Debug.draw_phys(!Debug.phys_drawing); };
Debug.inputs.f1.doc = "Draw physics debugging aids.";
//Debug.inputs.f3 = function() { Debug.draw_bb = !Debug.draw_bb; };
//Debug.inputs.f3.doc = "Toggle drawing bounding boxes.";
Debug.inputs.f4 = function() {
Debug.draw_names = !Debug.draw_names;
Debug.draw_gizmos = !Debug.draw_gizmos;
};
Debug.inputs.f4.doc = "Toggle drawing gizmos and names of objects.";
2023-09-12 00:02:57 -05:00
Debug.Options.gif = {
w: 640, /* Max width */
h: 480, /* Max height */
stretch: false, /* True if you want to stretch */
cpf: 4,
depth: 16,
2023-09-12 00:02:57 -05:00
file: "out.gif",
rec: false,
secs: 6,
start_time: 0,
fps: 0,
start() {
var w = this.w;
var h = this.h;
if (!this.stretch) {
var win = Window.height / Window.width;
var gif = h/w;
if (gif > win)
h = w * win;
else
w = h / win;
}
cmd(131, w, h, this.cpf, this.depth);
this.rec = true;
this.fps = (1/this.cpf)*100;
this.start_time = time.now();
timer.oneshot(this.stop.bind(this), this.secs, this, true);
},
stop() {
if (!this.rec) return;
cmd(132, this.file);
this.rec = false;
},
2023-09-12 00:02:57 -05:00
};
Debug.inputs.f8 = function() {
var now = new Date();
Debug.Options.gif.file = now.toISOString() + ".gif";
Debug.Options.gif.start();
};
Debug.inputs.f9 = function() {
Debug.Options.gif.stop();
}
2023-09-12 00:02:57 -05:00
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.f12 = function() { GUI.defaults.debug = !GUI.defaults.debug; console.warn("GUI toggle debug");};
Debug.inputs.f12.doc = "Toggle drawing GUI debugging aids.";
Debug.inputs['M-1'] = render.normal;
Debug.inputs['M-2'] = render.wireframe;
2023-08-17 20:13:17 -05:00
Debug.inputs['C-M-f'] = function() {};
Debug.inputs['C-M-f'].doc = "Enter camera fly mode.";
2024-02-25 17:31:48 -06:00
Debug.api = {};
Debug.api.doc_entry = function(obj, key)
{
2024-02-23 16:05:30 -06:00
if (typeof key !== 'string') {
console.warn("Cannot print a key that isn't a string.");
return undefined;
}
var title = key;
var o = obj[key];
if (typeof o === 'undefined' && obj.impl && typeof obj.impl[key] !== 'undefined')
o = obj.impl[key];
var t = typeof o;
2024-02-23 16:05:30 -06:00
if (Array.isArray(o)) t = "array";
else if (t === 'function') {
title = o.toString().tofirst(')') + ")";
2024-02-23 16:05:30 -06:00
title = title.fromfirst('(');
title = key + "(" + title;
if (o.doc) doc = o.doc;
t = "";
2024-02-23 16:05:30 -06:00
} else if (t === 'undefined') t = "";
2024-02-23 16:05:30 -06:00
if (t) t = "**" + t + "**\n";
2024-02-23 16:05:30 -06:00
var doc = "";
if (o.doc) doc = o.doc;
else if (obj.doc && obj.doc[key]) doc = obj.doc[key];
else if (Array.isArray(o)) doc = json.encode(o);
2024-02-23 16:05:30 -06:00
return `## ${title}
${t}
${doc}
`;
}
2024-02-25 17:31:48 -06:00
Debug.api.print_doc = function(name)
{
2024-02-23 16:05:30 -06:00
var obj = name;
if (typeof name === 'string') {
obj = eval(name);
if (!obj) {
console.warn(`Cannot print the API of '${name}', as it was not found.`);
return undefined;
}
obj = globalThis[name];
}
obj = eval(name);
if (!Object.isObject(obj)) {
console.warn("Cannot print the API of something that isn't an object.");
return undefined;
}
2024-02-23 16:05:30 -06:00
if (!obj) {
console.warn(`Object '${name}' does not exist.`);
return;
}
var mdoc = "# " + name + "\n";
if (obj.doc?.doc) mdoc += obj.doc.doc + "\n";
else if (typeof obj.doc === 'string') mdoc += obj.doc + "\n";
2024-02-23 16:05:30 -06:00
for (var key in obj) {
if (key === 'doc') continue;
2023-10-26 11:48:02 -05:00
if (key === 'toString') continue;
2024-02-23 16:05:30 -06:00
2024-02-25 17:31:48 -06:00
mdoc += Debug.api.doc_entry(obj, key) + "\n";
}
return mdoc;
}
return {
Debug,
2024-03-01 11:45:06 -06:00
Gizmos,
assert
}