private vars

This commit is contained in:
2025-12-19 00:10:19 -06:00
parent 0bc0472a2f
commit 4bdbde52a0
21 changed files with 73 additions and 179 deletions

View File

@@ -7,4 +7,6 @@ rtree = "gitea.pockle.world/john/cell-rtree"
dmon = "gitea.pockle.world/john/cell-watch" dmon = "gitea.pockle.world/john/cell-watch"
libsamplerate = "gitea.pockle.world/john/cell-libsamplerate" libsamplerate = "gitea.pockle.world/john/cell-libsamplerate"
sdl3 = "gitea.pockle.world/john/cell-sdl3" sdl3 = "gitea.pockle.world/john/cell-sdl3"
image = "gitea.pockle.world/john/cell-image"
soundwave = "gitea.pockle.world/john/soundwave"

View File

@@ -25,7 +25,7 @@ prosperon.on('key_down', function key_down(e) {
}) })
prosperon.on('quit', function() { prosperon.on('quit', function() {
$_.stop() $stop()
}) })
prosperon.on('key_up', function key_up(e) { prosperon.on('key_up', function key_up(e) {

View File

@@ -56,13 +56,13 @@ var hello = use('examples/hello')
log.console(hello.greet('Cell')) log.console(hello.greet('Cell'))
$_.receiver(function(msg) { $receiver(function(msg) {
if (msg.type == 'ping') { if (msg.type == 'ping') {
send(msg, {type:'pong'}) send(msg, {type:'pong'})
} }
}) })
$_.delay(_ => $_.stop(), 0.1) $delay(_ => $stop(), 0.1)
``` ```
Run it: Run it:
@@ -71,7 +71,7 @@ Run it:
Notes: Notes:
- Modules are `*.cm` and must return a value. The engine deepfreezes return values, so mutate via new objects or closures rather than inplace. - Modules are `*.cm` and must return a value. The engine deepfreezes return values, so mutate via new objects or closures rather than inplace.
- Programs are `*.ce` and must not return a value. They run toptobottom 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 toptobottom when spawned and can register handlers via `$receiver()` and schedule work via `$delay()` or `$clock()`.
## 5) Spawning Child Programs (Actors) ## 5) Spawning Child Programs (Actors)
@@ -80,19 +80,19 @@ Programs can spawn other programs and receive lifecycle events.
- File: `examples/spawner.ce` - File: `examples/spawner.ce`
```javascript ```javascript
$_.receiver(function(e) { $receiver(function(e) {
if (e.type == 'greet' && e.actor) { if (e.type == 'greet' && e.actor) {
log.console('Child greeted me') log.console('Child greeted me')
} }
}) })
$_.start(function(info) { $start(function(info) {
if (info.type == 'greet') { if (info.type == 'greet') {
log.console('Spawned child actor') log.console('Spawned child actor')
} }
}, 'examples/hello.ce') }, 'examples/hello.ce')
$_.delay(_ => $_.stop(), 0.5) $delay(_ => $stop(), 0.5)
``` ```
Run it: Run it:

View File

@@ -287,11 +287,11 @@ function startServer() {
isMyTurn = true; isMyTurn = true;
updateTitle(); updateTitle();
$_.portal(e => { $portal(e => {
log.console("Portal received contact message"); log.console("Portal received contact message");
// Reply with this actor to establish connection // Reply with this actor to establish connection
log.console (json.encode($_)) log.console ($self)
send(e, $_); send(e, $self);
log.console("Portal replied with server actor"); log.console("Portal replied with server actor");
}, 5678); }, 5678);
} }
@@ -309,22 +309,22 @@ function joinServer() {
// Send a greet message with our actor object // Send a greet message with our actor object
send(opponent, { send(opponent, {
type: 'greet', type: 'greet',
client_actor: $_ client_actor: $self
}); });
} else { } else {
log.console(`Failed to connect: ${json.encode(reason)}`); log.console(`Failed to connect: ${reason}`);
gameState = 'waiting'; gameState = 'waiting';
updateTitle(); updateTitle();
} }
} }
$_.contact(contact_fn, { $contact(contact_fn, {
address: "192.168.0.149", address: "192.168.0.149",
port: 5678 port: 5678
}); });
} }
$_.receiver(e => { $receiver(e => {
if (e.kind == 'update') if (e.kind == 'update')
send(e, update(e.dt)) send(e, update(e.dt))
else if (e.kind == 'draw') else if (e.kind == 'draw')
@@ -336,7 +336,7 @@ $_.receiver(e => {
log.console("Server received greet from client"); log.console("Server received greet from client");
// Store the client's actor object for ongoing communication // Store the client's actor object for ongoing communication
opponent = e.client_actor; opponent = e.client_actor;
log.console("Stored client actor:", json.encode(opponent)); log.console("Stored client actor:", opponent);
gameState = 'connected'; gameState = 'connected';
updateTitle(); updateTitle();

View File

@@ -8,8 +8,8 @@ var os = use('os')
var staef = use('staef') var staef = use('staef')
var qoi = use('qoi') var qoi = use('qoi')
var LASTUSE = key() var LASTUSE = "graphics:lastuse"
var LOADING = key() var LOADING = "graphics:loading"
var cache = {} var cache = {}

View File

@@ -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

View File

@@ -10,6 +10,7 @@ var geometry = use('geometry')
var blob = use('blob') var blob = use('blob')
var imgui = use('imgui') var imgui = use('imgui')
var utf8 = use('utf8') var utf8 = use('utf8')
var json = use('json')
var os = use('os') var os = use('os')
var math = use('math/radians') var math = use('math/radians')
@@ -620,7 +621,7 @@ function poll_input() {
} }
if (event.type == 'quit') if (event.type == 'quit')
$_.stop() $stop()
if (event.type.includes('key')) { if (event.type.includes('key')) {
if (event.key) if (event.key)
@@ -641,7 +642,7 @@ function poll_input() {
} }
input_cb(evs) input_cb(evs)
$_.delay(poll_input, input_rate) $delay(poll_input, input_rate)
} }
prosperon.input = function(fn) prosperon.input = function(fn)
@@ -673,7 +674,7 @@ var sprite_pipeline = {
blend: alpha_blend_state blend: alpha_blend_state
} }
var GPU = key() var GPU = "prosperon:gpu"
var cur_cam var cur_cam
var cmd_fns = {} var cmd_fns = {}
@@ -1170,7 +1171,7 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
if (done) done() if (done) done()
} }
var shop = use('shop') var shop = use('util')
////////// dmon hot reload //////// ////////// dmon hot reload ////////
function poll_file_changes() { function poll_file_changes() {
dmon.poll(e => { 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') var dmon = use('dmon/dmon')

View File

@@ -80,7 +80,7 @@ function allocate_id() {
} }
// Message handler // Message handler
$_.receiver(function(msg) { $receiver(function(msg) {
if (!msg.kind || !msg.op) { if (!msg.kind || !msg.op) {
send(msg, {error: "Message must have 'kind' and 'op' fields"}); send(msg, {error: "Message must have 'kind' and 'op' fields"});
return; return;
@@ -88,7 +88,7 @@ $_.receiver(function(msg) {
var response = {}; var response = {};
// log.console(json.encode(msg)) // log.console(msg)
try { try {
switch (msg.kind) { switch (msg.kind) {
@@ -562,7 +562,7 @@ function handle_texture(msg) {
}); });
} }
else { else {
log.console(json.encode(msg.data)) log.console(msg.data)
return {error: "Must provide either surface_id or width/height"}; return {error: "Must provide either surface_id or width/height"};
} }

View File

@@ -246,7 +246,7 @@ function pump() {
cleanup() cleanup()
} }
$_.delay(pump, 1/240) $delay(pump, 1/240)
} }
pump() pump()

View File

@@ -98,7 +98,7 @@ function loop(){
} }
/* schedule next tick: aim for 60 Hz but wont matter to anim speed */ /* schedule next tick: aim for 60 Hz but wont 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(); loop();

View File

@@ -78,7 +78,7 @@ function loop()
sprite.forEach(x => x.move(x.dir.scale(dt))) sprite.forEach(x => x.move(x.dir.scale(dt)))
var queue = sprite.queue() var queue = sprite.queue()
//log.console(json.encode(queue)) //log.console(queue)
for (var q of queue) { for (var q of queue) {
if (!q.image) continue if (!q.image) continue
@@ -99,7 +99,7 @@ function loop()
} }
var delay = (1/60) - dt var delay = (1/60) - dt
$_.delay(loop, delay) $delay(loop, delay)
} }
loop() loop()

View File

@@ -77,7 +77,7 @@ function loop()
if (delay <= 0) if (delay <= 0)
loop() loop()
else else
$_.delay(loop, delay) $delay(loop, delay)
} }
var sound = use('sound') var sound = use('sound')

View File

@@ -6,7 +6,7 @@ var json = use('json');
var cameras = camera.list(); var cameras = camera.list();
if (cameras.length == 0) { if (cameras.length == 0) {
log.console("No cameras found!"); log.console("No cameras found!");
$_. stop(); $ stop();
} }
var cam_id = cameras[0]; var cam_id = cameras[0];
@@ -69,4 +69,4 @@ for (var cs in colorspaces) {
} }
log.console("\nColorspace test complete!"); log.console("\nColorspace test complete!");
$_.stop(); $stop();

View File

@@ -7,7 +7,7 @@ var json = use('json');
var cameras = camera.list(); var cameras = camera.list();
if (cameras.length == 0) { if (cameras.length == 0) {
log.console("No cameras found!"); log.console("No cameras found!");
$_.stop(); $stop();
} }
var cam_id = cameras[0]; var cam_id = cameras[0];
@@ -17,7 +17,7 @@ log.console("Using camera:", camera.name(cam_id));
var cam = camera.open(cam_id); var cam = camera.open(cam_id);
if (!cam) { if (!cam) {
log.console("Failed to open camera!"); log.console("Failed to open camera!");
$_.stop(); $stop();
} }
// Get the format being used // Get the format being used
@@ -29,20 +29,20 @@ log.console(" Colorspace:", format.colorspace);
// Handle camera approval // Handle camera approval
var approved = false; var approved = false;
$_.receiver(e => { $receiver(e => {
if (e.type == 'camera_device_approved') { if (e.type == 'camera_device_approved') {
log.console("\nCamera approved!"); log.console("\nCamera approved!");
approved = true; approved = true;
} else if (e.type == 'camera_device_denied') { } else if (e.type == 'camera_device_denied') {
log.error("Camera access denied!"); log.error("Camera access denied!");
$_.stop(); $stop();
} }
}); });
// Wait for approval then capture // Wait for approval then capture
function capture_test() { function capture_test() {
if (!approved) { if (!approved) {
$_.delay(capture_test, 0.1); $delay(capture_test, 0.1);
return; return;
} }
@@ -51,7 +51,7 @@ function capture_test() {
if (!surf) { if (!surf) {
log.console("No frame captured yet, retrying..."); log.console("No frame captured yet, retrying...");
$_.delay(capture_test, 0.1); $delay(capture_test, 0.1);
return; return;
} }
@@ -99,8 +99,8 @@ function capture_test() {
} }
log.console("\nTest complete!"); log.console("\nTest complete!");
$_.stop(); $stop();
} }
// Start capture test after a short delay // Start capture test after a short delay
$_.delay(capture_test, 0.5); $delay(capture_test, 0.5);

View File

@@ -4,7 +4,7 @@ var graphics
var os = use('os'); var os = use('os');
var input = use('input') var input = use('input')
var math = use('math/radians') var math = use('math/radians')
input.watch($_) input.watch($self)
// Create SDL video actor // Create SDL video actor
var video_actor = use('sdl/video'); var video_actor = use('sdl/video');
@@ -12,8 +12,8 @@ var video_actor = use('sdl/video');
var window_id = null; var window_id = null;
var renderer_id = null; var renderer_id = null;
$_.receiver(e => { $receiver(e => {
log.console(json.encode(e)) log.console(e)
}) })
// Create window // Create window
@@ -53,7 +53,7 @@ send(video_actor, {
graphics = use('graphics', video_actor, renderer_id) graphics = use('graphics', video_actor, renderer_id)
// Start drawing after a short delay // 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) // Schedule next frame (60 FPS)
if (frame < 600) { // Run for 10 seconds if (frame < 600) { // Run for 10 seconds
$_.delay(draw_frame, 1/60); $delay(draw_frame, 1/60);
} else { } else {
log.console("Test completed - drew", frame, "frames"); 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 // Stop after 12 seconds if not already stopped
$_.delay($_.stop, 12); $delay($stop, 12);

View File

@@ -56,7 +56,7 @@ function draw()
return draw2d.get_commands() return draw2d.get_commands()
} }
$_.receiver(e => { $receiver(e => {
if (e.kind == 'update') if (e.kind == 'update')
send(e, update(e.dt)) send(e, update(e.dt))
else if (e.kind == 'draw') else if (e.kind == 'draw')

View File

@@ -5,7 +5,7 @@ var Surface = use('sdl/surface');
var surf = new Surface({width: 100, height: 100}); var surf = new Surface({width: 100, height: 100});
log.console("Created surface:", surf.width, "x", surf.height); log.console("Created surface:", surf.width, "x", surf.height);
log.console(json.encode(surf)) log.console(surf)
// Test fill // Test fill
surf.fill([1, 0, 0, 1]); // Red surf.fill([1, 0, 0, 1]); // Red

View File

@@ -60,4 +60,4 @@ for (var i = 0; i < yuv_tests.length; i++) {
} }
log.console("\nColorspace conversion test complete!"); log.console("\nColorspace conversion test complete!");
$_.stop(); $stop();

View File

@@ -5,7 +5,7 @@ var os = use('os');
var input = use('input') var input = use('input')
var json = use('json') var json = use('json')
var surface = use('sdl/surface') var surface = use('sdl/surface')
input.watch($_) input.watch($self)
// Create SDL video actor // Create SDL video actor
var video_actor = use('sdl/video'); var video_actor = use('sdl/video');
@@ -19,13 +19,13 @@ var cam_approved = false;
var webcam_texture = null; var webcam_texture = null;
// Handle camera events // Handle camera events
$_.receiver(e => { $receiver(e => {
if (e.type == 'camera_device_approved' && e.which == cam_id) { if (e.type == 'camera_device_approved' && e.which == cam_id) {
log.console("Camera approved!"); log.console("Camera approved!");
cam_approved = true; cam_approved = true;
} else if (e.type == 'camera_device_denied' && e.which == cam_id) { } else if (e.type == 'camera_device_denied' && e.which == cam_id) {
log.error("Camera access denied!"); log.error("Camera access denied!");
$_.stop(); $stop();
} }
}) })
@@ -69,8 +69,8 @@ send(video_actor, {
var cameras = camera.list(); var cameras = camera.list();
if (cameras.length == 0) { if (cameras.length == 0) {
log.error("No cameras found!"); log.error("No cameras found!");
log.console(json.encode(cameras)) log.console(cameras)
$_.stop(); $stop();
return; return;
} }
@@ -117,7 +117,7 @@ send(video_actor, {
if (!cam_obj) { if (!cam_obj) {
log.error("Failed to open camera!"); log.error("Failed to open camera!");
$_.stop(); $stop();
return; return;
} }
@@ -132,7 +132,7 @@ send(video_actor, {
log.console(" FPS:", actual_format.framerate_numerator + "/" + actual_format.framerate_denominator); log.console(" FPS:", actual_format.framerate_numerator + "/" + actual_format.framerate_denominator);
// Start capturing after a short delay to wait for approval // 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() { function start_capturing() {
if (!cam_approved) { if (!cam_approved) {
log.console("Waiting for camera approval..."); log.console("Waiting for camera approval...");
$_.delay(start_capturing, 0.1); $delay(start_capturing, 0.1);
return; return;
} }
@@ -229,7 +229,7 @@ function start_capturing() {
// Schedule next frame (30 FPS for webcam) // Schedule next frame (30 FPS for webcam)
if (frame < 300) { // Run for 10 seconds if (frame < 300) { // Run for 10 seconds
$_.delay(capture_and_draw, 1/30); $delay(capture_and_draw, 1/30);
} else { } else {
log.console("Test completed - captured", frame, "frames"); 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 // Note: Camera is automatically closed when the object is garbage collected
cam_obj = null; cam_obj = null;
$_.delay($_.stop, 0.5); $delay($stop, 0.5);
} }
} }
capture_and_draw(); capture_and_draw();
} }
$_.delay(_ => { $delay(_ => {
// Capture frame from camera // Capture frame from camera
var surface = cam_obj.capture().convert("rgba8888", "srgb") var surface = cam_obj.capture().convert("rgba8888", "srgb")
log.console('capturing!') log.console('capturing!')
@@ -260,4 +260,4 @@ $_.delay(_ => {
}, 3) }, 3)
// Stop after 12 seconds if not already stopped // Stop after 12 seconds if not already stopped
$_.delay($_.stop, 12); $delay($stop, 12);

View File

@@ -30,11 +30,11 @@ function loop() {
ren.draw_color([0,0,0,1]) ren.draw_color([0,0,0,1])
ren.fillrect({x:50,y:50,height:50,width:50}) ren.fillrect({x:50,y:50,height:50,width:50})
ren.present() ren.present()
$_.delay(loop, 1/60) $delay(loop, 1/60)
} }
loop() loop()
$_.delay($_.stop, 3) $delay($stop, 3)
var os = use('os') var os = use('os')
var actor = use('actor') var actor = use('actor')
@@ -45,12 +45,12 @@ ioguy[cell.actor_sym] = {
send(ioguy, { send(ioguy, {
type: "subscribe", type: "subscribe",
actor: $_ actor: $self
}) })
$_.receiver(e => { $receiver(e => {
if (e.type == 'quit') if (e.type == 'quit')
os.exit() os.exit()
else else
log.console(json.encode(e)) log.console(e)
}) })

View File

@@ -171,7 +171,7 @@ Timeline.prototype.play = function() {
this.last_tick = now this.last_tick = now
this.current_time += dt this.current_time += dt
this.seek(this.current_time) this.seek(this.current_time)
$_.delay(loop, rate) $delay(loop, rate)
} }
loop() loop()
} }
@@ -207,7 +207,7 @@ Timeline.prototype.toJSON = function() {
// Live update loop for fire-and-forget tweens // Live update loop for fire-and-forget tweens
function live_update_loop() { function live_update_loop() {
TweenEngine.update() TweenEngine.update()
$_.delay(live_update_loop, rate) $delay(live_update_loop, rate)
} }
// Factory function // Factory function
@@ -227,7 +227,7 @@ function init(default_clock) {
} }
// Auto-init with real time if not explicitly initialized // Auto-init with real time if not explicitly initialized
$_.delay(() => { $delay(() => {
if (!TweenEngine.default_clock) { if (!TweenEngine.default_clock) {
init() init()
} }