add some lodash
This commit is contained in:
parent
f35c77c4a9
commit
6f9137746a
|
@ -1554,10 +1554,23 @@ Math.sign = function (n) {
|
|||
return n >= 0 ? 1 : -1;
|
||||
};
|
||||
|
||||
var lodash = {};
|
||||
lodash.get = function(obj, path, defValue) {
|
||||
if (!path) return undefined
|
||||
// Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
|
||||
var pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g)
|
||||
var result = pathArray.reduce(
|
||||
(prevObj, key) => prevObj && prevObj[key],
|
||||
obj
|
||||
)
|
||||
return result === undefined ? defValue : result
|
||||
}
|
||||
|
||||
return {
|
||||
convert,
|
||||
time,
|
||||
Vector,
|
||||
bbox,
|
||||
yaml,
|
||||
lodash
|
||||
};
|
||||
|
|
|
@ -49,9 +49,8 @@ profile.ms = function (t) {
|
|||
|
||||
var callgraph = {};
|
||||
profile.rawstacks = {};
|
||||
profile.cpu_cg = callgraph;
|
||||
|
||||
function add_callgraph(fn, line, time) {
|
||||
function add_callgraph(fn, line, time, alone) {
|
||||
var cc = callgraph[line];
|
||||
if (!cc) {
|
||||
var cc = {};
|
||||
|
@ -60,9 +59,18 @@ function add_callgraph(fn, line, time) {
|
|||
cc.hits = 0;
|
||||
cc.fn = fn;
|
||||
cc.line = line;
|
||||
cc.alone = {
|
||||
time: 0,
|
||||
hits: 0
|
||||
}
|
||||
}
|
||||
cc.time += time;
|
||||
cc.hits++;
|
||||
|
||||
if (alone) {
|
||||
cc.alone.time += time;
|
||||
cc.alone.hits++;
|
||||
}
|
||||
}
|
||||
|
||||
var hittar = 500; // number of call instructions before getting a new frame
|
||||
|
@ -73,9 +81,11 @@ profile.cpu_start = undefined;
|
|||
|
||||
profile.clear_cpu = function () {
|
||||
callgraph = {};
|
||||
profile.cpu_instr = undefined;
|
||||
};
|
||||
|
||||
profile.start_cpu_gather = function (gathertime = 5) {
|
||||
profile.clear_cpu();
|
||||
// gather cpu frames for 'time' seconds
|
||||
if (profile.cpu_start) return;
|
||||
profile.cpu_start = profile.now();
|
||||
|
@ -100,7 +110,8 @@ profile.start_cpu_gather = function (gathertime = 5) {
|
|||
var lines = stack.map(x => x[1]).filter(x => x);
|
||||
lines = lines.map(x => x.slice(1, x.length - 1));
|
||||
|
||||
for (var i = 0; i < fns.length; i++) add_callgraph(fns[i], lines[i], time);
|
||||
add_callgraph(fns[0], lines[0], time, true);
|
||||
for (var i = 1; i < fns.length; i++) add_callgraph(fns[i], lines[i], time, false);
|
||||
|
||||
st = profile.now();
|
||||
if (profile.secs(st - profile.cpu_start) < gathertime) profile.gather_rate(Math.variate(hittar, hitpct));
|
||||
|
@ -108,21 +119,30 @@ profile.start_cpu_gather = function (gathertime = 5) {
|
|||
profile.gather_stop();
|
||||
profile.cpu_start = undefined;
|
||||
var e = Object.values(callgraph);
|
||||
e = e.sort((a, b) => {
|
||||
if (a.time > b.time) return -1;
|
||||
return 1;
|
||||
});
|
||||
e = e.filter( x=> x.line);
|
||||
|
||||
for (var x of e) {
|
||||
var ffs = x.line.split(":");
|
||||
|
||||
x.timestr = profile.best_t(x.time);
|
||||
var pct = (profile.secs(x.time) / gathertime) * 100;
|
||||
x.timeper = x.time / x.hits;
|
||||
x.timeperstr = profile.best_t(x.timeper);
|
||||
x.pct = (profile.secs(x.time) / gathertime) * 100;
|
||||
x.alone.timestr = profile.best_t(x.alone.time);
|
||||
x.alone.timeper = x.alone.time/x.alone.hits;
|
||||
x.alone.timeperstr = profile.best_t(x.alone.timeper);
|
||||
x.alone.pct = (profile.secs(x.alone.time)/gathertime*100);
|
||||
x.fncall = get_line(ffs[0], ffs[1]);
|
||||
x.log = `${x.line}::${x.fn}:: ${x.timestr} (${pct.toPrecision(3)}%) (${x.hits} hits) --> ${get_line(ffs[0], ffs[1])}`;
|
||||
x.log = x.line + " " + x.fn + " " + x.fncall;
|
||||
x.incl = {
|
||||
time: x.time,
|
||||
timestr: x.timestr,
|
||||
timeper: x.timeper,
|
||||
timeperstr: x.timeperstr,
|
||||
hits: x.hits,
|
||||
pct: x.pct,
|
||||
};
|
||||
}
|
||||
|
||||
profile.cpu_instr = e;
|
||||
}
|
||||
});
|
||||
|
@ -179,17 +199,12 @@ profile.best_t = function (t) {
|
|||
return `${t.toPrecision(4)} ${t_units[qq]}`;
|
||||
};
|
||||
|
||||
profile.report = function (start, msg = "[undefined report]") {
|
||||
console.info(`${msg} in ${profile.best_t(profile.now() - start)}`);
|
||||
};
|
||||
|
||||
/*
|
||||
Frame averages are an instrumented profiling technique. Place frame() calls
|
||||
in your code to get a call graph for things you are interested in.
|
||||
*/
|
||||
|
||||
var frame_avg = false;
|
||||
profile.frame_avg_t = 72000;
|
||||
|
||||
profile.start_frame_avg = function () {
|
||||
if (frame_avg) return;
|
||||
|
@ -219,6 +234,7 @@ var pframe = 0;
|
|||
var profile_stack = [];
|
||||
|
||||
profile.frame = function profile_frame(title) {
|
||||
return;
|
||||
if (profile.cpu_start) return;
|
||||
if (!frame_avg) return;
|
||||
|
||||
|
@ -236,29 +252,12 @@ profile.frame = function profile_frame(title) {
|
|||
};
|
||||
|
||||
profile.endframe = function profile_endframe() {
|
||||
return;
|
||||
if (!frame_avg) return;
|
||||
profile_cframe.time = profile.now() - profile_cframe.time;
|
||||
profile_cframe = profile_frame_ts.pop();
|
||||
};
|
||||
|
||||
var print_frame = function (frame, indent, title) {
|
||||
say(indent + `${title} ::::: ${profile.best_t(Math.mean(frame._times))} ± ${profile.best_t(Math.ci(frame._times))} (${frame._times.length} hits)`);
|
||||
|
||||
for (var i in frame) {
|
||||
if (i === "_times") continue;
|
||||
print_frame(frame[i], indent + " ", i);
|
||||
}
|
||||
};
|
||||
|
||||
profile.print_frame_avg = function () {
|
||||
say("===FRAME AVERAGES===\n");
|
||||
|
||||
var indent = "";
|
||||
for (var i in profile_frames) print_frame(profile_frames[i], "", "frame");
|
||||
|
||||
say("\n");
|
||||
};
|
||||
|
||||
/*
|
||||
Cache reporting is to measure how long specific events take, that are NOT every frame
|
||||
Useful to measure things like how long it takes to make a specific creature
|
||||
|
@ -329,6 +328,18 @@ function printreport(cache, name) {
|
|||
profile.data = {};
|
||||
profile.curframe = 0;
|
||||
|
||||
profile.snapshot = {};
|
||||
var fps = [];
|
||||
|
||||
profile.report_frame = function(t)
|
||||
{
|
||||
fps.push(t);
|
||||
if (fps.length > 15) {
|
||||
profile.snapshot.fps = Math.mean(fps);
|
||||
fps = [];
|
||||
}
|
||||
}
|
||||
|
||||
function prof_add_stats(obj, stat) {
|
||||
for (var i in stat) {
|
||||
obj[i] ??= [];
|
||||
|
@ -337,10 +348,13 @@ function prof_add_stats(obj, stat) {
|
|||
}
|
||||
|
||||
profile.pushdata = function (arr, val) {
|
||||
|
||||
if (arr.last() !== val) arr[profile.curframe] = val;
|
||||
};
|
||||
|
||||
profile.capturing = false;
|
||||
profile.capture_data = function () {
|
||||
if (!profile.capturing && profile.data.memory.malloc_size) return;
|
||||
prof_add_stats(profile.data.memory, os.mem());
|
||||
prof_add_stats(profile.data.gfx, imgui.framestats());
|
||||
prof_add_stats(profile.data.actors, actor.__stats());
|
||||
|
|
|
@ -758,7 +758,7 @@ function flush_img() {
|
|||
function img_e() {
|
||||
img_idx++;
|
||||
if (img_idx > img_cache.length) {
|
||||
e = {
|
||||
var e = {
|
||||
transform: os.make_transform(),
|
||||
shade: Color.white,
|
||||
rect: [0, 0, 1, 1],
|
||||
|
@ -766,12 +766,10 @@ function img_e() {
|
|||
img_cache.push(e);
|
||||
return e;
|
||||
}
|
||||
var e = img_cache[img_idx - 1];
|
||||
e.transform.unit();
|
||||
return e;
|
||||
return img_cache[img_idx - 1];
|
||||
}
|
||||
|
||||
render.image = function (tex, pos, scale, rotation = 0, color = Color.white) {
|
||||
render.image = function image(tex, pos, scale, rotation = 0, color = Color.white) {
|
||||
if (typeof tex === "string") {
|
||||
tex = game.texture(tex);
|
||||
scale.x ??= tex.width;
|
||||
|
@ -790,8 +788,7 @@ render.image = function (tex, pos, scale, rotation = 0, color = Color.white) {
|
|||
}
|
||||
|
||||
var e = img_e();
|
||||
e.transform.move(pos);
|
||||
if (scale) e.transform.scale = scale.div([tex.width, tex.height]);
|
||||
e.transform.trs(pos, undefined, scale ? scale.div([tex.width, tex.height]) : undefined);
|
||||
e.shade = color;
|
||||
|
||||
return;
|
||||
|
@ -978,7 +975,11 @@ prosperon.make_camera = function () {
|
|||
var screencolor;
|
||||
|
||||
globalThis.imtoggle = function (name, obj, field) {
|
||||
var changed = false;
|
||||
var old = obj[field];
|
||||
obj[field] = imgui.checkbox(name, obj[field]);
|
||||
if (old !== obj[field]) return true;
|
||||
return false;
|
||||
};
|
||||
var replstr = "";
|
||||
|
||||
|
@ -1120,6 +1121,9 @@ prosperon.render = function () {
|
|||
profile.endframe();
|
||||
|
||||
render.end_pass();
|
||||
|
||||
profile.report_frame(profile.secs(profile.now())-frame_t);
|
||||
|
||||
render.commit();
|
||||
|
||||
endframe();
|
||||
|
@ -1179,6 +1183,7 @@ prosperon.process = function process() {
|
|||
profile.endframe();
|
||||
|
||||
profile.capture_data();
|
||||
|
||||
};
|
||||
|
||||
return { render };
|
||||
|
|
|
@ -450,14 +450,39 @@ JSC_SCALL(imgui_context,
|
|||
)
|
||||
|
||||
JSC_SCALL(imgui_table,
|
||||
if (ImGui::BeginTable(str, js2number(argv[1]))) {
|
||||
int flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingStretchProp;
|
||||
bool sort = false;
|
||||
if (!JS_IsUndefined(argv[3])) sort = true;
|
||||
|
||||
if (sort) flags |= ImGuiTableFlags_Sortable;
|
||||
if (ImGui::BeginTable(str, js2number(argv[1]), flags)) {
|
||||
script_call_sym(argv[2],0,NULL);
|
||||
|
||||
if (sort) {
|
||||
ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs();
|
||||
if (sort_specs && sort_specs->SpecsDirty) {
|
||||
for (int i = 0; i < sort_specs->SpecsCount; i++)
|
||||
{
|
||||
const ImGuiTableColumnSortSpecs* spec = &sort_specs->Specs[i];
|
||||
JSValue send[2];
|
||||
send[0] = number2js(spec->ColumnIndex);
|
||||
send[1] = boolean2js(spec->SortDirection == ImGuiSortDirection_Ascending);
|
||||
script_call_sym(argv[3], 2, send);
|
||||
JS_FreeValue(js, send[0]);
|
||||
JS_FreeValue(js, send[1]);
|
||||
}
|
||||
sort_specs->SpecsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
)
|
||||
|
||||
JSC_CCALL(imgui_tablenextrow, ImGui::TableNextRow())
|
||||
JSC_CCALL(imgui_tablenextcolumn, ImGui::TableNextColumn())
|
||||
JSC_SCALL(imgui_tablesetupcolumn, ImGui::TableSetupColumn(str))
|
||||
JSC_CCALL(imgui_tableheadersrow, ImGui::TableHeadersRow())
|
||||
|
||||
JSC_SCALL(imgui_dnd,
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
|
@ -883,9 +908,11 @@ static const JSCFunctionListEntry js_imgui_funcs[] = {
|
|||
MIST_FUNC_DEF(imgui, popup, 2),
|
||||
MIST_FUNC_DEF(imgui, close_popup,0),
|
||||
MIST_FUNC_DEF(imgui, context,2),
|
||||
MIST_FUNC_DEF(imgui, table, 3),
|
||||
MIST_FUNC_DEF(imgui, table, 4),
|
||||
MIST_FUNC_DEF(imgui, tablenextcolumn,0),
|
||||
MIST_FUNC_DEF(imgui, tablenextrow,0),
|
||||
MIST_FUNC_DEF(imgui, tableheadersrow, 0),
|
||||
MIST_FUNC_DEF(imgui, tablesetupcolumn, 1),
|
||||
MIST_FUNC_DEF(imgui, dnd, 3),
|
||||
MIST_FUNC_DEF(imgui, dndtarget, 2),
|
||||
MIST_FUNC_DEF(imgui, color, 2),
|
||||
|
|
|
@ -2013,10 +2013,18 @@ JSC_CCALL(transform_unit,
|
|||
t->scale = v3one;
|
||||
)
|
||||
|
||||
JSC_CCALL(transform_trs,
|
||||
transform *t = js2transform(self);
|
||||
t->pos = JS_IsUndefined(argv[0]) ? v3zero : js2vec3(argv[0]);
|
||||
t->rotation = JS_IsUndefined(argv[1]) ? QUAT1 : js2quat(argv[1]);
|
||||
t->scale = JS_IsUndefined(argv[2]) ? v3one : js2vec3(argv[1]);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_transform_funcs[] = {
|
||||
CGETSET_ADD(transform, pos),
|
||||
CGETSET_ADD(transform, scale),
|
||||
CGETSET_ADD(transform, rotation),
|
||||
MIST_FUNC_DEF(transform, trs, 3),
|
||||
MIST_FUNC_DEF(transform, phys2d, 3),
|
||||
MIST_FUNC_DEF(transform, move, 1),
|
||||
MIST_FUNC_DEF(transform, rotate, 2),
|
||||
|
|
Loading…
Reference in a new issue