update
This commit is contained in:
@@ -53,6 +53,11 @@ const libraries = [
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const benchmarks = [
|
||||
{
|
||||
name: "Empty object",
|
||||
data: [{}, {}, {}, {}],
|
||||
iterations: 10000
|
||||
},
|
||||
{
|
||||
name: "Small Integers",
|
||||
data: [0, 42, -1, 2023],
|
||||
@@ -125,8 +130,8 @@ function runBenchmarkForLibrary(lib, bench) {
|
||||
let encodeTime = measureTime(() => {
|
||||
for (let i = 0; i < bench.iterations; i++) {
|
||||
// For each data item, encode it
|
||||
for (let d of bench.data) {
|
||||
let e = lib.encode(d);
|
||||
for (let j = 0; j < bench.data.length; j++) {
|
||||
let e = lib.encode(bench.data[j]);
|
||||
// store only in the very first iteration, so we can decode them later
|
||||
// but do not store them every iteration or we blow up memory.
|
||||
if (i === 0) {
|
||||
@@ -171,8 +176,8 @@ for (let bench of benchmarks) {
|
||||
let decOpsPerSec = (totalOps / decodeTime).toFixed(1);
|
||||
|
||||
console.log(` ${lib.name}:`);
|
||||
console.log(` Encode time: ${encodeTime.toFixed(3)}s => ${encOpsPerSec} encodes/sec`);
|
||||
console.log(` Decode time: ${decodeTime.toFixed(3)}s => ${decOpsPerSec} decodes/sec`);
|
||||
console.log(` Encode time: ${encodeTime.toFixed(3)}s => ${encOpsPerSec} encodes/sec [${(encodeTime/bench.iterations)*1000000000} ns/try]`);
|
||||
console.log(` Decode time: ${decodeTime.toFixed(3)}s => ${decOpsPerSec} decodes/sec [${(decodeTime/bench.iterations)*1000000000}/try]`);
|
||||
console.log(` Total size: ${totalSize} bytes (or code units for JSON)`);
|
||||
console.log("");
|
||||
}
|
||||
@@ -180,3 +185,5 @@ for (let bench of benchmarks) {
|
||||
}
|
||||
|
||||
console.log("Benchmark complete.\n");
|
||||
|
||||
os.exit()
|
||||
|
||||
@@ -353,8 +353,8 @@ function handle_renderer(msg) {
|
||||
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
||||
ren.texture(
|
||||
resources.texture[tex_id],
|
||||
msg.data.src || {x:0, y:0, w:1, h:1},
|
||||
msg.data.dst || {x:0, y:0, w:100, h:100},
|
||||
msg.data.src,
|
||||
msg.data.dst,
|
||||
msg.data.angle || 0,
|
||||
msg.data.anchor || {x:0.5, y:0.5}
|
||||
);
|
||||
|
||||
@@ -183,15 +183,6 @@ draw.slice9 = function slice9(image, rect = [0,0], slice = 0, info = slice9_info
|
||||
material: material
|
||||
})
|
||||
}
|
||||
draw.slice9[prosperon.DOC] = `
|
||||
:param image: An image object or string path to a texture.
|
||||
:param rect: A rectangle specifying draw location/size, default [0, 0].
|
||||
:param slice: The pixel inset or spacing for the 9-slice (number or object).
|
||||
:param info: A slice9 info object controlling tiling of edges/corners.
|
||||
:param material: Material/styling information
|
||||
:return: None
|
||||
:raises Error: If no image is provided.
|
||||
`
|
||||
|
||||
draw.image = function image(image, rect = [0,0], rotation = 0, anchor = [0,0], shear = [0,0], info = {}, material) {
|
||||
if (!image) throw Error('Need an image to render.')
|
||||
@@ -228,15 +219,5 @@ draw.text = function text(text, rect, font = 'fonts/c64.ttf', size = 8, color =
|
||||
material: {color}
|
||||
})
|
||||
}
|
||||
draw.text[prosperon.DOC] = `
|
||||
:param text: The string to draw.
|
||||
:param rect: A rectangle specifying draw position (and possibly wrapping area).
|
||||
:param font: A font object or string path, default sysfont.
|
||||
:param size: Font size in pixels.
|
||||
:param color: The text color, default color.white.
|
||||
:param wrap: Pixel width for text wrapping, default 0 (no wrap).
|
||||
:param material: Material/styling information
|
||||
:return: None
|
||||
`
|
||||
|
||||
return draw
|
||||
@@ -159,11 +159,8 @@ function create_image(path){
|
||||
let raw = decode_image(bytes, path.ext());
|
||||
|
||||
/* ── Case A: static image ─────────────────────────────────── */
|
||||
if(raw.surface) {
|
||||
console.log("STATIC!")
|
||||
console.log(json.encode(raw.surface))
|
||||
if(raw.surface)
|
||||
return make_handle(raw.surface);
|
||||
}
|
||||
|
||||
/* ── Case B: GIF helpers returned array [surf, …] ─────────── */
|
||||
if(Array.isArray(raw))
|
||||
|
||||
@@ -1568,6 +1568,9 @@ void ffi_load(JSContext *js)
|
||||
arrput(rt->module_registry, MISTLINE(rtree));
|
||||
arrput(rt->module_registry, MISTLINE(sprite));
|
||||
arrput(rt->module_registry, MISTLINE(transform));
|
||||
|
||||
arrput(rt->module_registry, MISTLINE(wota));
|
||||
arrput(rt->module_registry, MISTLINE(nota));
|
||||
|
||||
#ifndef NSTEAM
|
||||
arrput(rt->module_registry, MISTLINE(steam));
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
static int tracy_profiling_enabled = 0;
|
||||
|
||||
#define ENGINE "scripts/core/engine.js"
|
||||
|
||||
static prosperon_rt **ready_queue = NULL;
|
||||
@@ -331,7 +333,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
||||
{
|
||||
SDL_LockMutex(actor->turn);
|
||||
#ifdef TRACY_ENABLE
|
||||
TracyCFiberEnter(actor->name);
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberEnter(actor->name);
|
||||
#endif
|
||||
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
@@ -420,7 +423,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
||||
|
||||
END:
|
||||
#ifdef TRACY_ENABLE
|
||||
TracyCFiberLeave(actor->name);
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberLeave(actor->name);
|
||||
#endif
|
||||
SDL_UnlockMutex(actor->turn);
|
||||
set_actor_state(actor);
|
||||
@@ -428,7 +432,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
||||
|
||||
KILL:
|
||||
#ifdef TRACY_ENABLE
|
||||
TracyCFiberLeave(actor->id);
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberLeave(actor->name);
|
||||
#endif
|
||||
SDL_UnlockMutex(actor->turn);
|
||||
actor_free(actor);
|
||||
@@ -614,6 +619,9 @@ static tracy_stack_t *get_tracy_stack(void)
|
||||
|
||||
void tracy_call_hook(JSContext *js, JSValue fn)
|
||||
{
|
||||
if (!tracy_profiling_enabled)
|
||||
return;
|
||||
|
||||
tracy_stack_t *stack = get_tracy_stack();
|
||||
js_debug debug;
|
||||
js_debug_info(js, fn, &debug);
|
||||
@@ -626,6 +634,9 @@ void tracy_call_hook(JSContext *js, JSValue fn)
|
||||
|
||||
void tracy_end_hook(JSContext *js, JSValue fn)
|
||||
{
|
||||
if (!tracy_profiling_enabled)
|
||||
return;
|
||||
|
||||
tracy_stack_t *stack = get_tracy_stack();
|
||||
if (arrlen(stack->arr) > 0)
|
||||
___tracy_emit_zone_end(arrpop(stack->arr));
|
||||
@@ -635,15 +646,20 @@ void script_startup(prosperon_rt *prt, void (*hook)(JSContext*))
|
||||
{
|
||||
JSRuntime *rt;
|
||||
#ifdef TRACY_ENABLE
|
||||
rt = JS_NewRuntime2(&tracy_malloc_funcs, NULL);
|
||||
if (tracy_profiling_enabled)
|
||||
rt = JS_NewRuntime2(&tracy_malloc_funcs, NULL);
|
||||
else
|
||||
rt = JS_NewRuntime();
|
||||
#else
|
||||
rt = JS_NewRuntime();
|
||||
#endif
|
||||
JSContext *js = JS_NewContextRaw(rt);
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
js_debug_sethook(js, tracy_call_hook, JS_HOOK_CALL);
|
||||
js_debug_sethook(js, tracy_end_hook, JS_HOOK_RET);
|
||||
if (tracy_profiling_enabled) {
|
||||
js_debug_sethook(js, tracy_call_hook, JS_HOOK_CALL);
|
||||
js_debug_sethook(js, tracy_end_hook, JS_HOOK_RET);
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_AddIntrinsicBaseObjects(js);
|
||||
@@ -1455,7 +1471,17 @@ bool event_watch(void *data, SDL_Event *e)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *new_cwd = NULL;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
int profile_enabled = 0;
|
||||
int script_start = 1;
|
||||
|
||||
// Check for --profile flag first
|
||||
if (argc > 1 && strcmp(argv[1], "--profile") == 0) {
|
||||
profile_enabled = 1;
|
||||
script_start = 2;
|
||||
}
|
||||
|
||||
// Check for --cwd flag
|
||||
for (int i = script_start; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--cwd") == 0) {
|
||||
i++;
|
||||
if (i < argc) new_cwd = argv[i];
|
||||
@@ -1468,6 +1494,10 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
queue_event = SDL_RegisterEvents(1);
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
tracy_profiling_enabled = profile_enabled;
|
||||
#endif
|
||||
|
||||
main_thread = SDL_GetCurrentThreadID();
|
||||
|
||||
@@ -1495,7 +1525,11 @@ int main(int argc, char **argv)
|
||||
event_watchers_mutex = SDL_CreateMutex();
|
||||
|
||||
/* Create the initial actor from the main command line. */
|
||||
create_actor(argc, argv, NULL);
|
||||
/* Adjust argc and argv to skip --profile if present */
|
||||
int actor_argc = argc - (script_start - 1);
|
||||
char **actor_argv = argv + (script_start - 1);
|
||||
actor_argv[0] = argv[0]; // Keep the program name
|
||||
create_actor(actor_argc, actor_argv, NULL);
|
||||
|
||||
cores = 1;
|
||||
|
||||
|
||||
@@ -97,9 +97,9 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
|
||||
int tag = JS_VALUE_GET_TAG(replaced);
|
||||
switch (tag) {
|
||||
case JS_TAG_INT: {
|
||||
double d;
|
||||
JS_ToFloat64(ctx, &d, replaced);
|
||||
wota_write_number(&enc->wb, d);
|
||||
int32_t d;
|
||||
JS_ToInt32(ctx, &d, replaced);
|
||||
wota_write_int_word(&enc->wb, d);
|
||||
break;
|
||||
}
|
||||
case JS_TAG_FLOAT64:
|
||||
@@ -109,7 +109,7 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
|
||||
wota_write_sym(&enc->wb, WOTA_NULL);
|
||||
break;
|
||||
}
|
||||
wota_write_number(&enc->wb, d);
|
||||
wota_write_float_word(&enc->wb, d);
|
||||
break;
|
||||
}
|
||||
case JS_TAG_STRING: {
|
||||
|
||||
@@ -79,6 +79,8 @@ void wota_write_record (WotaBuffer *wb, unsigned long long count);
|
||||
void wota_write_number (WotaBuffer *wb, double n);
|
||||
/* Symbol codes (WOTA_NULL, WOTA_FALSE, etc.) */
|
||||
void wota_write_sym (WotaBuffer *wb, int sym_code);
|
||||
void wota_write_int_word(WotaBuffer *wb, long long val);
|
||||
void wota_write_float_word(WotaBuffer *wb, double val);
|
||||
|
||||
|
||||
#ifdef WOTA_IMPLEMENTATION
|
||||
@@ -496,7 +498,7 @@ static int fits_in_56_bits(long long x)
|
||||
Write a WOTA_INT (single 64-bit word):
|
||||
top 56 bits = signed integer (arithmetic shift), LSB=0x00
|
||||
*/
|
||||
static void wota_write_int_word(WotaBuffer *wb, long long val)
|
||||
void wota_write_int_word(WotaBuffer *wb, long long val)
|
||||
{
|
||||
/* shift 'val' left by 8 bits into the top 56,
|
||||
then OR the type code in the bottom byte. */
|
||||
@@ -511,7 +513,7 @@ static void wota_write_int_word(WotaBuffer *wb, long long val)
|
||||
first word => type=0x01 in LSB, top 56 bits=0
|
||||
second word => raw IEEE 754 double bits
|
||||
*/
|
||||
static void wota_write_float_word(WotaBuffer *wb, double val)
|
||||
void wota_write_float_word(WotaBuffer *wb, double val)
|
||||
{
|
||||
uint64_t *p = wota_buffer_alloc(wb, 2);
|
||||
p[0] = (uint64_t)WOTA_FLOAT; /* top 56 bits=0, LSB=0x01 */
|
||||
|
||||
@@ -9,6 +9,8 @@ var transform = use('transform');
|
||||
var rasterize = use('rasterize');
|
||||
var video_actor = use('sdl_video')
|
||||
|
||||
var graphics
|
||||
|
||||
var window
|
||||
var render
|
||||
|
||||
@@ -42,12 +44,18 @@ send(video_actor, {
|
||||
}
|
||||
|
||||
render = e.id
|
||||
graphics = use('graphics', video_actor, e.id)
|
||||
console.log(`Created window and renderer id ${render}`)
|
||||
})
|
||||
})
|
||||
|
||||
var last = os.now()
|
||||
|
||||
// FPS tracking
|
||||
var fps_samples = []
|
||||
var fps_sample_count = 60
|
||||
var fps_sum = 0
|
||||
|
||||
// Engine state
|
||||
var camera = {
|
||||
x: 0,
|
||||
@@ -56,8 +64,12 @@ var camera = {
|
||||
rotation: 0
|
||||
}
|
||||
|
||||
var images = {}
|
||||
|
||||
|
||||
// Convert high-level draw commands to low-level renderer commands
|
||||
function translate_draw_commands(commands) {
|
||||
if (!graphics) return
|
||||
var renderer_commands = []
|
||||
|
||||
commands.forEach(function(cmd) {
|
||||
@@ -152,10 +164,16 @@ function translate_draw_commands(commands) {
|
||||
break
|
||||
|
||||
case "draw_image":
|
||||
var img = graphics.texture(cmd.image)
|
||||
if (!img.gpu) break
|
||||
// TODO: Handle image loading and texture management
|
||||
renderer_commands.push({
|
||||
op: "texture",
|
||||
data: cmd
|
||||
data: {
|
||||
texture_id: img.gpu.id,
|
||||
dst: {x: cmd.rect.x, y: cmd.rect.y, width: img.width, height:img.height},
|
||||
src: {x:0,y:0,width:img.width,height:img.height},
|
||||
}
|
||||
})
|
||||
break
|
||||
|
||||
@@ -215,7 +233,27 @@ function loop()
|
||||
data: batch_commands
|
||||
}, _ => {
|
||||
var diff = os.now() - now
|
||||
$_.delay(loop,1/240)
|
||||
|
||||
// Calculate and track FPS
|
||||
var frame_time = os.now() - last
|
||||
if (frame_time > 0) {
|
||||
var current_fps = 1 / frame_time
|
||||
|
||||
// Add to samples
|
||||
fps_samples.push(current_fps)
|
||||
fps_sum += current_fps
|
||||
|
||||
// Keep only the last N samples
|
||||
if (fps_samples.length > fps_sample_count) {
|
||||
fps_sum -= fps_samples.shift()
|
||||
}
|
||||
|
||||
// Calculate average FPS
|
||||
var avg_fps = fps_sum / fps_samples.length
|
||||
console.log(`FPS: ${avg_fps.toFixed(1)}`)
|
||||
}
|
||||
|
||||
loop()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -50,6 +50,8 @@ function draw()
|
||||
{color: color.yellow}
|
||||
)
|
||||
|
||||
draw2d.image("tests/bunny")
|
||||
|
||||
// Return the draw commands
|
||||
return draw2d.get_commands()
|
||||
}
|
||||
|
||||
1
tests/spawnee.js
Normal file
1
tests/spawnee.js
Normal file
@@ -0,0 +1 @@
|
||||
console.log("im alive")
|
||||
12
tests/spawner.js
Normal file
12
tests/spawner.js
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
function spawnem()
|
||||
{
|
||||
for (var i = 0; i < 10; i++)
|
||||
$_.start(_ => {}, "tests/spawnee.js")
|
||||
}
|
||||
|
||||
with ([1,2,3]) {
|
||||
console.log(toString())
|
||||
}
|
||||
|
||||
$_.delay(spawnem, 3)
|
||||
Reference in New Issue
Block a user