diff --git a/cell.toml b/cell.toml index bca3d464..8997f49d 100644 --- a/cell.toml +++ b/cell.toml @@ -7,4 +7,6 @@ rtree = "gitea.pockle.world/john/cell-rtree" dmon = "gitea.pockle.world/john/cell-watch" libsamplerate = "gitea.pockle.world/john/cell-libsamplerate" sdl3 = "gitea.pockle.world/john/cell-sdl3" +image = "gitea.pockle.world/john/cell-image" +soundwave = "gitea.pockle.world/john/soundwave" diff --git a/controller.cm b/controller.cm index 620b48e2..39a826ea 100644 --- a/controller.cm +++ b/controller.cm @@ -25,7 +25,7 @@ prosperon.on('key_down', function key_down(e) { }) prosperon.on('quit', function() { - $_.stop() + $stop() }) prosperon.on('key_up', function key_up(e) { diff --git a/docs/quickstart.md b/docs/quickstart.md index 87a862bf..fd2fe9cd 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -56,13 +56,13 @@ var hello = use('examples/hello') log.console(hello.greet('Cell')) -$_.receiver(function(msg) { +$receiver(function(msg) { if (msg.type == 'ping') { send(msg, {type:'pong'}) } }) -$_.delay(_ => $_.stop(), 0.1) +$delay(_ => $stop(), 0.1) ``` Run it: @@ -71,7 +71,7 @@ Run it: Notes: - Modules are `*.cm` and must return a value. The engine deep‑freezes return values, so mutate via new objects or closures rather than in‑place. -- Programs are `*.ce` and must not return a value. They run top‑to‑bottom when spawned and can register handlers via `$_.receiver()` and schedule work via `$_.delay()` or `$_.clock()`. +- Programs are `*.ce` and must not return a value. They run top‑to‑bottom when spawned and can register handlers via `$receiver()` and schedule work via `$delay()` or `$clock()`. ## 5) Spawning Child Programs (Actors) @@ -80,19 +80,19 @@ Programs can spawn other programs and receive lifecycle events. - File: `examples/spawner.ce` ```javascript -$_.receiver(function(e) { +$receiver(function(e) { if (e.type == 'greet' && e.actor) { log.console('Child greeted me') } }) -$_.start(function(info) { +$start(function(info) { if (info.type == 'greet') { log.console('Spawned child actor') } }, 'examples/hello.ce') -$_.delay(_ => $_.stop(), 0.5) +$delay(_ => $stop(), 0.5) ``` Run it: diff --git a/examples/chess/chess.ce b/examples/chess/chess.ce index 036345db..d27fdc86 100644 --- a/examples/chess/chess.ce +++ b/examples/chess/chess.ce @@ -287,11 +287,11 @@ function startServer() { isMyTurn = true; updateTitle(); - $_.portal(e => { + $portal(e => { log.console("Portal received contact message"); // Reply with this actor to establish connection - log.console (json.encode($_)) - send(e, $_); + log.console ($self) + send(e, $self); log.console("Portal replied with server actor"); }, 5678); } @@ -309,22 +309,22 @@ function joinServer() { // Send a greet message with our actor object send(opponent, { type: 'greet', - client_actor: $_ + client_actor: $self }); } else { - log.console(`Failed to connect: ${json.encode(reason)}`); + log.console(`Failed to connect: ${reason}`); gameState = 'waiting'; updateTitle(); } } - $_.contact(contact_fn, { + $contact(contact_fn, { address: "192.168.0.149", port: 5678 }); } -$_.receiver(e => { +$receiver(e => { if (e.kind == 'update') send(e, update(e.dt)) else if (e.kind == 'draw') @@ -336,7 +336,7 @@ $_.receiver(e => { log.console("Server received greet from client"); // Store the client's actor object for ongoing communication opponent = e.client_actor; - log.console("Stored client actor:", json.encode(opponent)); + log.console("Stored client actor:", opponent); gameState = 'connected'; updateTitle(); diff --git a/graphics.cm b/graphics.cm index f0c73f4d..bcc9c399 100644 --- a/graphics.cm +++ b/graphics.cm @@ -8,8 +8,8 @@ var os = use('os') var staef = use('staef') var qoi = use('qoi') -var LASTUSE = key() -var LOADING = key() +var LASTUSE = "graphics:lastuse" +var LOADING = "graphics:loading" var cache = {} diff --git a/lcdsprite.cm b/lcdsprite.cm deleted file mode 100644 index 3d93dbf6..00000000 --- a/lcdsprite.cm +++ /dev/null @@ -1,109 +0,0 @@ -// TODO: this needs totally rearchitected - -var sprite = {} - -var graphics = use('graphics') -var render = use('render') -var draw2d = use('draw2d') -var sprite = use('sprite') - -var SPRITE = key() /* raw C sprite */ -var POS = key() /* cached JS copies of simple data */ -var ROT = key() -var SCALE = key() -var SKEW = key() -var CENTER = key() -var COLOR = key() -var IMAGE = key() - -var ursprite = { - get pos() { return this[POS] }, - set pos(v) { - this[POS] = v - this[SPRITE].pos = v - }, - - get center() { return this[CENTER] }, - set center(v){ - this[CENTER] = v - this[SPRITE].center = v - }, - - get rotation() { return this[ROT] }, - set rotation(t){ - this[ROT] = t - this[SPRITE].rotation = t * 2*Math.PI /* C expects radians */ - this[SPRITE].set_affine() - }, - - get scale() { return this[SCALE] }, - set scale(v){ - this[SCALE] = v - this[SPRITE].scale = v - this[SPRITE].set_affine() - }, - - get skew() { return this[SKEW] }, - set skew(v){ - this[SKEW] = v - this[SPRITE].skew = v - this[SPRITE].set_affine() - }, - - get layer() { return this[SPRITE].layer }, - set layer(n){ this[SPRITE].layer = n }, - - get color() { return this[COLOR] }, - set color(v){ - this[COLOR] = v - this[SPRITE].color = v - }, - - move(mv) { this[SPRITE].move(mv) }, - moveto(p){ - this.pos = p - }, - - get image() { return this[IMAGE] }, - set image(img) { - this[IMAGE] = img - this[SPRITE].set_image(img) - } -} - -var _sprites = [] - -var def_sprite = stone({ - pos: [0,0], - rotation: 0, - scale: [1,1], - center: [0,0], - color: [1,1,1,1], - skew: [0,0], - layer: 0, -}) - -sprite.create = function(image, info) { - info.__proto__ = def_sprite - var sp = meme(ursprite) - sp[SPRITE] = new sprite(info) - sp.image = graphics.texture(image) - - _sprites.push(sp) - return sp -} - -sprite.forEach = fn => { for (let s of _sprites) fn(s) } -sprite.values = () => _sprites.slice() -sprite.geometry= () => graphics.make_sprite_mesh(_sprites) - -var raws = [] -sprite.queue = function() { - if (raws.length != _sprites.length) - raws.length = _sprites.length - - for (var i = 0; i < _sprites.length; i++) raws[i] = _sprites[i] - return graphics.make_sprite_queue(_sprites.map(x => x[SPRITE])) -} - -return sprite diff --git a/prosperon.cm b/prosperon.cm index 4df49b45..b6e338a7 100644 --- a/prosperon.cm +++ b/prosperon.cm @@ -10,6 +10,7 @@ var geometry = use('geometry') var blob = use('blob') var imgui = use('imgui') var utf8 = use('utf8') +var json = use('json') var os = use('os') var math = use('math/radians') @@ -620,7 +621,7 @@ function poll_input() { } if (event.type == 'quit') - $_.stop() + $stop() if (event.type.includes('key')) { if (event.key) @@ -641,7 +642,7 @@ function poll_input() { } input_cb(evs) - $_.delay(poll_input, input_rate) + $delay(poll_input, input_rate) } prosperon.input = function(fn) @@ -673,7 +674,7 @@ var sprite_pipeline = { blend: alpha_blend_state } -var GPU = key() +var GPU = "prosperon:gpu" var cur_cam var cmd_fns = {} @@ -1170,7 +1171,7 @@ prosperon.create_batch = function create_batch(draw_cmds, done) { if (done) done() } -var shop = use('shop') +var shop = use('util') ////////// dmon hot reload //////// function poll_file_changes() { dmon.poll(e => { @@ -1199,7 +1200,7 @@ function poll_file_changes() { } }) - $_.delay(poll_file_changes, 0.5) + $delay(poll_file_changes, 0.5) } var dmon = use('dmon/dmon') diff --git a/sdl/video.ce b/sdl/video.ce index 14ba0283..62c56f38 100644 --- a/sdl/video.ce +++ b/sdl/video.ce @@ -80,7 +80,7 @@ function allocate_id() { } // Message handler -$_.receiver(function(msg) { +$receiver(function(msg) { if (!msg.kind || !msg.op) { send(msg, {error: "Message must have 'kind' and 'op' fields"}); return; @@ -88,7 +88,7 @@ $_.receiver(function(msg) { var response = {}; -// log.console(json.encode(msg)) +// log.console(msg) try { switch (msg.kind) { @@ -562,7 +562,7 @@ function handle_texture(msg) { }); } else { - log.console(json.encode(msg.data)) + log.console(msg.data) return {error: "Must provide either surface_id or width/height"}; } diff --git a/sound.cm b/sound.cm index 114a3659..3a838d4e 100644 --- a/sound.cm +++ b/sound.cm @@ -246,7 +246,7 @@ function pump() { cleanup() } - $_.delay(pump, 1/240) + $delay(pump, 1/240) } pump() diff --git a/tests/animation.ce b/tests/animation.ce index 3f400094..078165fd 100644 --- a/tests/animation.ce +++ b/tests/animation.ce @@ -98,7 +98,7 @@ function loop(){ } /* schedule next tick: aim for 60 Hz but won’t matter to anim speed */ - $_.delay(loop, number.max(0, (1/60) - (os.now()-now))); + $delay(loop, number.max(0, (1/60) - (os.now()-now))); } loop(); diff --git a/tests/bunnymark.ce b/tests/bunnymark.ce index 7695b021..bc97c123 100644 --- a/tests/bunnymark.ce +++ b/tests/bunnymark.ce @@ -78,7 +78,7 @@ function loop() sprite.forEach(x => x.move(x.dir.scale(dt))) var queue = sprite.queue() - //log.console(json.encode(queue)) + //log.console(queue) for (var q of queue) { if (!q.image) continue @@ -99,7 +99,7 @@ function loop() } var delay = (1/60) - dt - $_.delay(loop, delay) + $delay(loop, delay) } loop() diff --git a/tests/camera.ce b/tests/camera.ce index 359555b7..63a4f386 100644 --- a/tests/camera.ce +++ b/tests/camera.ce @@ -77,7 +77,7 @@ function loop() if (delay <= 0) loop() else - $_.delay(loop, delay) + $delay(loop, delay) } var sound = use('sound') diff --git a/tests/camera_colorspace.ce b/tests/camera_colorspace.ce index d656338e..7344816c 100644 --- a/tests/camera_colorspace.ce +++ b/tests/camera_colorspace.ce @@ -6,7 +6,7 @@ var json = use('json'); var cameras = camera.list(); if (cameras.length == 0) { log.console("No cameras found!"); - $_. stop(); + $ stop(); } var cam_id = cameras[0]; @@ -69,4 +69,4 @@ for (var cs in colorspaces) { } log.console("\nColorspace test complete!"); -$_.stop(); \ No newline at end of file +$stop(); \ No newline at end of file diff --git a/tests/camera_colorspace_convert.ce b/tests/camera_colorspace_convert.ce index ef0dce74..001b5b85 100644 --- a/tests/camera_colorspace_convert.ce +++ b/tests/camera_colorspace_convert.ce @@ -7,7 +7,7 @@ var json = use('json'); var cameras = camera.list(); if (cameras.length == 0) { log.console("No cameras found!"); - $_.stop(); + $stop(); } var cam_id = cameras[0]; @@ -17,7 +17,7 @@ log.console("Using camera:", camera.name(cam_id)); var cam = camera.open(cam_id); if (!cam) { log.console("Failed to open camera!"); - $_.stop(); + $stop(); } // Get the format being used @@ -29,20 +29,20 @@ log.console(" Colorspace:", format.colorspace); // Handle camera approval var approved = false; -$_.receiver(e => { +$receiver(e => { if (e.type == 'camera_device_approved') { log.console("\nCamera approved!"); approved = true; } else if (e.type == 'camera_device_denied') { log.error("Camera access denied!"); - $_.stop(); + $stop(); } }); // Wait for approval then capture function capture_test() { if (!approved) { - $_.delay(capture_test, 0.1); + $delay(capture_test, 0.1); return; } @@ -51,7 +51,7 @@ function capture_test() { if (!surf) { log.console("No frame captured yet, retrying..."); - $_.delay(capture_test, 0.1); + $delay(capture_test, 0.1); return; } @@ -99,8 +99,8 @@ function capture_test() { } log.console("\nTest complete!"); - $_.stop(); + $stop(); } // Start capture test after a short delay -$_.delay(capture_test, 0.5); \ No newline at end of file +$delay(capture_test, 0.5); \ No newline at end of file diff --git a/tests/draw2d.ce b/tests/draw2d.ce index 0ed3a551..355d23f1 100644 --- a/tests/draw2d.ce +++ b/tests/draw2d.ce @@ -4,7 +4,7 @@ var graphics var os = use('os'); var input = use('input') var math = use('math/radians') -input.watch($_) +input.watch($self) // Create SDL video actor var video_actor = use('sdl/video'); @@ -12,8 +12,8 @@ var video_actor = use('sdl/video'); var window_id = null; var renderer_id = null; -$_.receiver(e => { - log.console(json.encode(e)) +$receiver(e => { + log.console(e) }) // Create window @@ -53,7 +53,7 @@ send(video_actor, { graphics = use('graphics', video_actor, renderer_id) // Start drawing after a short delay - $_.delay(start_drawing, 0.1); + $delay(start_drawing, 0.1); }); }); @@ -219,10 +219,10 @@ function start_drawing() { // Schedule next frame (60 FPS) if (frame < 600) { // Run for 10 seconds - $_.delay(draw_frame, 1/60); + $delay(draw_frame, 1/60); } else { log.console("Test completed - drew", frame, "frames"); - $_.delay($_.stop, 0.5); + $delay($stop, 0.5); } } @@ -230,4 +230,4 @@ function start_drawing() { } // Stop after 12 seconds if not already stopped -$_.delay($_.stop, 12); \ No newline at end of file +$delay($stop, 12); \ No newline at end of file diff --git a/tests/prosperon.ce b/tests/prosperon.ce index ae7dfc6f..4adb68a3 100644 --- a/tests/prosperon.ce +++ b/tests/prosperon.ce @@ -56,7 +56,7 @@ function draw() return draw2d.get_commands() } -$_.receiver(e => { +$receiver(e => { if (e.kind == 'update') send(e, update(e.dt)) else if (e.kind == 'draw') diff --git a/tests/surface.ce b/tests/surface.ce index d3ac3e68..23b1db2c 100644 --- a/tests/surface.ce +++ b/tests/surface.ce @@ -5,7 +5,7 @@ var Surface = use('sdl/surface'); var surf = new Surface({width: 100, height: 100}); log.console("Created surface:", surf.width, "x", surf.height); -log.console(json.encode(surf)) +log.console(surf) // Test fill surf.fill([1, 0, 0, 1]); // Red diff --git a/tests/surface_colorspace.ce b/tests/surface_colorspace.ce index b5fb6703..933d316e 100644 --- a/tests/surface_colorspace.ce +++ b/tests/surface_colorspace.ce @@ -60,4 +60,4 @@ for (var i = 0; i < yuv_tests.length; i++) { } log.console("\nColorspace conversion test complete!"); -$_.stop(); \ No newline at end of file +$stop(); \ No newline at end of file diff --git a/tests/webcam.ce b/tests/webcam.ce index ed7bafa7..44e0ed57 100644 --- a/tests/webcam.ce +++ b/tests/webcam.ce @@ -5,7 +5,7 @@ var os = use('os'); var input = use('input') var json = use('json') var surface = use('sdl/surface') -input.watch($_) +input.watch($self) // Create SDL video actor var video_actor = use('sdl/video'); @@ -19,13 +19,13 @@ var cam_approved = false; var webcam_texture = null; // Handle camera events -$_.receiver(e => { +$receiver(e => { if (e.type == 'camera_device_approved' && e.which == cam_id) { log.console("Camera approved!"); cam_approved = true; } else if (e.type == 'camera_device_denied' && e.which == cam_id) { log.error("Camera access denied!"); - $_.stop(); + $stop(); } }) @@ -69,8 +69,8 @@ send(video_actor, { var cameras = camera.list(); if (cameras.length == 0) { log.error("No cameras found!"); - log.console(json.encode(cameras)) - $_.stop(); + log.console(cameras) + $stop(); return; } @@ -117,7 +117,7 @@ send(video_actor, { if (!cam_obj) { log.error("Failed to open camera!"); - $_.stop(); + $stop(); return; } @@ -132,7 +132,7 @@ send(video_actor, { log.console(" FPS:", actual_format.framerate_numerator + "/" + actual_format.framerate_denominator); // Start capturing after a short delay to wait for approval - $_.delay(start_capturing, 0.5); + $delay(start_capturing, 0.5); }); }); @@ -141,7 +141,7 @@ var captured = false function start_capturing() { if (!cam_approved) { log.console("Waiting for camera approval..."); - $_.delay(start_capturing, 0.1); + $delay(start_capturing, 0.1); return; } @@ -229,7 +229,7 @@ function start_capturing() { // Schedule next frame (30 FPS for webcam) if (frame < 300) { // Run for 10 seconds - $_.delay(capture_and_draw, 1/30); + $delay(capture_and_draw, 1/30); } else { log.console("Test completed - captured", frame, "frames"); @@ -245,14 +245,14 @@ function start_capturing() { // Note: Camera is automatically closed when the object is garbage collected cam_obj = null; - $_.delay($_.stop, 0.5); + $delay($stop, 0.5); } } capture_and_draw(); } -$_.delay(_ => { +$delay(_ => { // Capture frame from camera var surface = cam_obj.capture().convert("rgba8888", "srgb") log.console('capturing!') @@ -260,4 +260,4 @@ $_.delay(_ => { }, 3) // Stop after 12 seconds if not already stopped -$_.delay($_.stop, 12); \ No newline at end of file +$delay($stop, 12); \ No newline at end of file diff --git a/tests/window.ce b/tests/window.ce index 2d0749fd..5f1f8ea9 100644 --- a/tests/window.ce +++ b/tests/window.ce @@ -30,11 +30,11 @@ function loop() { ren.draw_color([0,0,0,1]) ren.fillrect({x:50,y:50,height:50,width:50}) ren.present() - $_.delay(loop, 1/60) + $delay(loop, 1/60) } loop() -$_.delay($_.stop, 3) +$delay($stop, 3) var os = use('os') var actor = use('actor') @@ -45,12 +45,12 @@ ioguy[cell.actor_sym] = { send(ioguy, { type: "subscribe", - actor: $_ + actor: $self }) -$_.receiver(e => { +$receiver(e => { if (e.type == 'quit') os.exit() else - log.console(json.encode(e)) + log.console(e) }) diff --git a/tween.cm b/tween.cm index 1e653417..3877a06e 100644 --- a/tween.cm +++ b/tween.cm @@ -171,7 +171,7 @@ Timeline.prototype.play = function() { this.last_tick = now this.current_time += dt this.seek(this.current_time) - $_.delay(loop, rate) + $delay(loop, rate) } loop() } @@ -207,7 +207,7 @@ Timeline.prototype.toJSON = function() { // Live update loop for fire-and-forget tweens function live_update_loop() { TweenEngine.update() - $_.delay(live_update_loop, rate) + $delay(live_update_loop, rate) } // Factory function @@ -227,7 +227,7 @@ function init(default_clock) { } // Auto-init with real time if not explicitly initialized -$_.delay(() => { +$delay(() => { if (!TweenEngine.default_clock) { init() }