memory output

This commit is contained in:
John Alanbrook 2024-08-05 15:26:18 -05:00
parent 33d4ebf14a
commit ceb728b1a7
15 changed files with 226 additions and 56 deletions

View file

@ -1,13 +1,40 @@
var actor = {};
actor.spawn = function(script, config, callback){
if (typeof script !== 'string') return undefined;
var padawan = Object.create(actor);
use(script, padawan);
var actor_urs = {};
globalThis.class_use = function(script, config, base, callback)
{
if (!actor_urs[script]) {
var newur = Object.create(base);
actor_urs[script] = newur;
}
var padawan = Object.create(actor_urs[script]);
if (callback) callback(padawan);
if (typeof config === 'object')
Object.merge(padawan,config);
var file = Resources.find_script(script);
var script = Resources.replstrs(file);
script = `(function() {
var self = this;
var $ = this.__proto__;
${script};
})`;
var fn = os.eval(file,script);
fn.call(padawan);
return padawan;
}
actor.spawn = function(script, config){
if (typeof script !== 'string') return undefined;
var padawan = class_use(script, config, actor);
padawan.padawans = [];
padawan.timers = [];
padawan.master = this;

View file

@ -551,7 +551,7 @@ Object.defineProperty(Object.prototype, 'obscure', {
Object.defineProperty(Object.prototype, 'mixin', {
value: function(obj) {
if (typeof obj === 'string')
obj = use(obj, this);
obj = use(obj);
if (obj)
Object.mixin(this, obj);
@ -1418,8 +1418,7 @@ bbox.fromobjs = function(objs)
/* VECTORS */
var Vector = {};
Vector.length = function(v) { return Math.hypot(...v); }
Vector.length = vector.length;
Vector.norm = vector.norm;
Vector.project = vector.project;
Vector.dot = vector.dot;

View file

@ -1,5 +1,8 @@
"use math";
prosperon.gc_start = function(){}
prosperon.gc_end = function(){}
Object.defineProperty(String.prototype, 'rm', {
value: function(index, endidx = index+1) { return this.slice(0,index) + this.slice(endidx); }
});
@ -223,37 +226,38 @@ globalThis.global = globalThis;
var use_cache = {};
globalThis.use = function use(file, env = {}, script) {
globalThis.use = function use(file) {
file = Resources.find_script(file);
profile.cache("USE", file);
if (use_cache[file]) {
var ret = use_cache[file].call(env);
return;
var ret = use_cache[file]();
profile.endcache(" [cached]");
return ret;
}
script ??= Resources.replstrs(file);
var script = Resources.replstrs(file);
script = `(function() { var self = this; ${script}; })`;
var fn = os.eval(file, script);
use_cache[file] = fn;
var ret = fn.call(env);
var ret = fn();
profile.endcache();
return ret;
}
function stripped_use (file, env = {}, script) {
function stripped_use (file, script) {
file = Resources.find_script(file);
if (use_cache[file]) {
var ret = use_cache[file].call(env);
return;
var ret = use_cache[file]();
return ret;
}
script ??= Resources.replstrs(file);
script = `(function() { var self = this; ${script}; })`;
var fn = os.eval(file, script);
var ret = fn.call(env);
var ret = fn();
profile.endcache();
return ret;
@ -264,7 +268,7 @@ function bare_use(file)
var script = io.slurp(file);
if (!script) return;
script = `(function() { var self = this; ${script}; })`;
Object.assign(globalThis, os.eval(file, script).call(globalThis));
Object.assign(globalThis, os.eval(file, script)());
}
globalThis.debug = {};

View file

@ -146,16 +146,15 @@ var entity = {
},
spawn(text, config, callback) {
var ent = Object.create(entity);
ent.transform = os.make_transform();
ent.guid = prosperon.guid();
ent.components = {};
ent.objects = {};
ent.timers = {};
var ent = class_use(text, config, entity, function(ent) {
ent.transform = os.make_transform();
ent.guid = prosperon.guid();
ent.components = {};
ent.objects = {};
ent.timers = {};
ent.ur = {};
});
/*
if (!text)
ent.ur = emptyur;
else if (text instanceof Object) {// assume it's an ur
@ -169,12 +168,6 @@ var entity = {
config = [ent.ur.data, config];
}
if (typeof text === 'string')
use(text, ent);
else if (Array.isArray(text))
for (var path of text) use(path,ent);
profile.cache("ENTITY TIME", ent.ur.name);
var st = profile.now();
if (typeof config === 'string')
Object.merge(ent, json.decode(Resources.replstrs(config)));
else if (Array.isArray(config))
@ -187,6 +180,15 @@ var entity = {
Object.merge(ent,path);
};
if (typeof text === 'string') {
class_use(
use(text, ent);
}
else if (Array.isArray(text))
for (var path of text) use(path,ent);
profile.cache("ENTITY TIME", ent.ur.name);
*/
ent.reparent(this);
for (var [prop, p] of Object.entries(ent)) {

View file

@ -76,7 +76,7 @@ var pre = function(data)
if (data.pos) cursor = data.pos.slice();
data.drawpos = cursor.slice().add(data.offset);
if (data.opacity !== 1) {
if (data.opacity && data.opacity !== 1) {
data.color = data.color.slice();
data.color[3] = data.opacity;
}

View file

@ -16,6 +16,7 @@ function calc_cpu(fn, times, diff=0)
function empty_fn() {}
profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") {
var retgather = gathering_cpu;
profile.gather_stop();
var empty = calc_cpu(empty_fn, 100000);
var mean = Math.mean(empty);
@ -26,7 +27,10 @@ profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") {
var totalt = profile.best_t(elapsed);
say(`profile [${q}]: ${avgt} ± ${profile.best_t(Math.ci(series))} [${totalt} for ${times} loops]`);
start_prof_gather();
say(`result of function is ${fn()}`);
if (retgather)
profile.start_prof_gather();
}
profile.ms = function(t) { return t/1000000; }
@ -277,3 +281,25 @@ function printreport(cache, name) {
return report;
};
profile.best_mem = function(bytes)
{
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toPrecision(3) + ' ' + sizes[i];
}
profile.print_mem = function()
{
var mem = os.mem();
say('total memory used: ' + profile.best_mem(mem.memory_used_size));
delete mem.memory_used_size;
delete mem.malloc_size;
for (var i in mem) {
if (i.includes("size"))
say(" " + i + " :: " + profile.best_mem(mem[i]));
}
}
return {profile};

View file

@ -920,10 +920,13 @@ prosperon.render = function()
render.end_pass();
profile.endframe();
profile.frame("post process");
profile.endframe();
profile.endframe();
/* draw the image of the game world first */
render.glue_pass();
profile.frame("frame");
profile.frame("render");
profile.frame("post process");
render.viewport(...prosperon.camera.view());
render.use_shader(render.postshader);
render.use_mat({diffuse:prosperon.screencolor});
@ -1002,6 +1005,4 @@ prosperon.process = function process() {
profile.endframe();
}
return {render};

View file

@ -15,9 +15,11 @@ if (os.sys() === 'macos') {
}
//appy.inputs.f12 = function() { mum.debug = !mum.debug; }
appy.inputs.f12 = function() { profile.cpu_frame(); }
appy.inputs.f11 = window.toggle_fullscreen;
appy.inputs.f9 = function() { profile.print_mem(); }
appy.inputs.f10 = function() { profile.toggle_frame_avg(); }
appy.inputs.f11 = window.toggle_fullscreen;
appy.inputs.f12 = function() { profile.cpu_frame(); }
appy.inputs['M-f4'] = prosperon.quit;
player[0].control(appy);
@ -240,7 +242,7 @@ Cmdline.register_order("play", function(argv) {
if (argv[0])
io.chdir(argv[0]);
game.loadurs();
// game.loadurs();
if (!io.exists(projectfile)) {
say("No game to play. Try making one with 'prosperon init'.");
@ -320,7 +322,7 @@ Cmdline.register_order("about", function(argv) {
}, "Get information about this game.");
Cmdline.register_order("ur", function(argv) {
game.loadurs();
// game.loadurs();
for (var i of ur._list.sort()) say(i);
}, "Get information about the ur types in your game.");

View file

@ -33,6 +33,7 @@
#include "par/par_shapes.h"
#include "sokol_glue.h"
#include <chipmunk/chipmunk_unsafe.h>
#include <chipmunk/chipmunk_structs.h>
#include "gui.h"
#include "timer.h"
@ -1315,6 +1316,21 @@ JSC_CCALL(vector_angledist,
return number2js(dist);
)
JSC_CCALL(vector_length,
int len = js_arrlen(argv[0]);
switch(len) {
case 2: return number2js(HMM_LenV2(js2vec2(argv[0])));
case 3: return number2js(HMM_LenV3(js2vec3(argv[0])));
case 4: return number2js(HMM_LenV4(js2vec4(argv[0])));
}
double sum = 0;
for (int i = 0; i < len; i++)
sum += pow(js2number(js_getpropidx(argv[0], i)), 2);
return number2js(sqrt(sum));
)
double r2()
{
return (double)rand() / (double)RAND_MAX ;
@ -1415,7 +1431,8 @@ static const JSCFunctionListEntry js_vector_funcs[] = {
MIST_FUNC_DEF(vector, mean, 1),
MIST_FUNC_DEF(vector, sum, 1),
MIST_FUNC_DEF(vector, sigma, 1),
MIST_FUNC_DEF(vector, median, 1)
MIST_FUNC_DEF(vector, median, 1),
MIST_FUNC_DEF(vector, length, 1)
};
#define JS_HMM_FN(OP, HMM, SIGN) \
@ -2501,6 +2518,46 @@ JSC_CCALL(os_quit, quit();)
JSC_CCALL(os_exit, exit(js2number(argv[0]));)
JSC_CCALL(os_reindex_static, cpSpaceReindexStatic(space));
JSC_CCALL(os_gc, script_gc());
JSC_CCALL(os_mem_limit, script_mem_limit(js2number(argv[0])))
JSC_CCALL(os_gc_threshold, script_gc_threshold(js2number(argv[0])))
JSC_CCALL(os_max_stacksize, script_max_stacksize(js2number(argv[0])))
#define JSOBJ_ADD_FIELD(OBJ, STRUCT, FIELD, TYPE) \
js_setpropstr(OBJ, #FIELD, TYPE##2js(STRUCT.FIELD));\
#define JSJMEMRET(FIELD) JSOBJ_ADD_FIELD(ret, jsmem, FIELD, number)
JSC_CCALL(os_mem,
JSMemoryUsage jsmem;
JS_ComputeMemoryUsage(rt, &jsmem);
ret = JS_NewObject(js);
JSJMEMRET(malloc_size)
JSJMEMRET(malloc_limit)
JSJMEMRET(memory_used_size)
JSJMEMRET(memory_used_count)
JSJMEMRET(atom_count)
JSJMEMRET(atom_size)
JSJMEMRET(str_count)
JSJMEMRET(str_size)
JSJMEMRET(obj_count)
JSJMEMRET(obj_size)
JSJMEMRET(prop_count)
JSJMEMRET(prop_size)
JSJMEMRET(shape_count)
JSJMEMRET(shape_size)
JSJMEMRET(js_func_count)
JSJMEMRET(js_func_size)
JSJMEMRET(js_func_code_size)
JSJMEMRET(js_func_pc2line_count)
JSJMEMRET(js_func_pc2line_size)
JSJMEMRET(c_func_count)
JSJMEMRET(array_count)
JSJMEMRET(fast_array_count)
JSJMEMRET(fast_array_elements)
JSJMEMRET(binary_object_count)
JSJMEMRET(binary_object_size)
)
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
JSC_CCALL(os_make_body,
@ -2618,6 +2675,13 @@ JSC_CCALL(os_make_circle2d,
return ret;
)
JSC_CCALL(os_make_timer, return timer2js(timer_make()))
JSC_CCALL(os_update_timers, timer_update(js2number(argv[0])))
JSC_CCALL(os_obj_size,
)
JSC_CCALL(poly2d_setverts,
cpShape *s = js2cpShape(self);
HMM_Vec2 *v = js2cpvec2arr(argv[0]);
@ -2938,6 +3002,12 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_hemisphere, 2),
MIST_FUNC_DEF(os, make_plane, 2),
MIST_FUNC_DEF(os, make_video, 1),
MIST_FUNC_DEF(os, make_timer, 0),
MIST_FUNC_DEF(os, update_timers, 1),
MIST_FUNC_DEF(os, mem, 1),
MIST_FUNC_DEF(os, mem_limit, 1),
MIST_FUNC_DEF(os, gc_threshold, 1),
MIST_FUNC_DEF(os, max_stacksize, 1)
};
#include "steam.h"

View file

@ -110,6 +110,7 @@ JSValue TYPE##2js(TYPE *n) { \
return j; }\
\
static JSValue js_##TYPE##_memid (JSContext *js, JSValue self) { return str2js("%p", js2##TYPE(self)); } \
static JSValue js_##TYPE##_memsize (JSContext *js, JSValue self) { return number2js(sizeof(TYPE)); } \
#define QJSGLOBALCLASS(NAME) \
JSValue NAME = JS_NewObject(js); \
@ -126,6 +127,7 @@ 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_SetPropertyStr(js, TYPE##_proto, "memsize", JS_NewCFunction(js, &js_##TYPE##_memsize, "memsize", 0)); \
JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
#define countof(x) (sizeof(x)/sizeof((x)[0]))

View file

@ -16,6 +16,9 @@ JSRuntime *rt = NULL;
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP
#endif
static JSValue start_gc;
static JSValue end_gc;
void script_startup() {
rt = JS_NewRuntime();
js = JS_NewContext(rt);
@ -44,6 +47,9 @@ return;
}
void script_gc() { JS_RunGC(rt); }
void script_mem_limit(size_t limit) { JS_SetMemoryLimit(rt, limit); }
void script_gc_threshold(size_t threshold) { JS_SetGCThreshold(rt, threshold); }
void script_max_stacksize(size_t size) { JS_SetMaxStackSize(rt, size); }
void js_stacktrace() {
if (!js) return;
@ -52,6 +58,7 @@ void js_stacktrace() {
#endif
}
void script_evalf(const char *format, ...)
{
JSValue obj;

View file

@ -30,6 +30,9 @@ JSValue script_eval(const char *file, const char *script);
void script_call_sym(JSValue sym, int argc, JSValue *argv);
void script_gc();
void script_mem_limit(size_t limit);
void script_gc_threshold(size_t threshold);
void script_max_stacksize(size_t size);
#ifdef __cplusplus
}

View file

@ -32,6 +32,7 @@
#include <time.h>
#include <fenv.h>
#include <math.h>
#include <script.h>
#if defined(__APPLE__)
#include <malloc/malloc.h>
#elif defined(__linux__) || defined(__GLIBC__)
@ -112,6 +113,22 @@ void quickjs_set_dumpout(FILE *f)
//#define DUMP_PROMISE
//#define DUMP_READ_OBJECT
#ifdef DUMP
//#define DUMP_FREE
//#define DUMP_MEM
//#define DUMP_CLOSURE
#define DUMP_GC
//#define DUMP_GC_FREE
#define DUMP_LEAKS 1
//#define DUMP_OBJECTS
#define DUMP_CLOSURE
//#define DUMP_OBJECTS
//#define DUMP_ATOMS
//#define DUMP_SHAPES
//#define DUMP_MODULE_RESOLVE
//#define DUMP_PROMISE
#endif
/* test the GC by forcing it before each object allocation */
//#define FORCE_GC_AT_MALLOC

View file

@ -1,22 +1,33 @@
#include "timer.h"
#include <stdio.h>
#include "stb_ds.h"
timer *timers;
timer **timers;
timer *timer_make()
{
return NULL;
timer *t = calloc(sizeof(*t),1);
arrput(timers, t);
return t;
}
void timer_free(timer *t)
{
printf("before free arrlen if timers is now %d\n", arrlen(timers));
for (int i = 0; i < arrlen(timers); i++) {
if (timers[i] == t) {
arrdelswap(timers,i);
break;
}
}
free(t);
printf("arrlen if timers is now %d\n", arrlen(timers));
}
void timer_update(double dt)
{
for (int i = 0; i < arrlen(timers); i++) {
timers[i].remain -= dt;
timers[i]->remain -= dt;
}
}

View file

@ -5,7 +5,6 @@ typedef struct timer {
double remain;
} timer;
timer *timer_make();
void timer_free(timer *t);
void timer_update(double dt);