This commit is contained in:
2026-01-18 11:22:52 -06:00
parent 23dc5820ee
commit a199278e7d
36 changed files with 202 additions and 202 deletions

View File

@@ -24,7 +24,7 @@ var controller_map = {
action.get_icon_for_action = function(action)
{
var bindings = this.get_bindings_for_device(action)
if (!bindings.length) return null
if (!length(bindings)) return null
var primary_binding = bindings[0]
@@ -236,8 +236,8 @@ action.on_input = function(action_id, evt)
}
// Send all matched actions (only if we found mappings - this means it's a raw input)
if (matched_actions.length > 0) {
for (var i = 0; i < matched_actions.length; i++) {
if (length(matched_actions) > 0) {
for (var i = 0; i < length(matched_actions); i++) {
// scene.recurse(game.root, 'on_input', matched_actions[i], evt)
}
}
@@ -261,7 +261,7 @@ action.rebind_action = function(action_name, new_key) {
// Clear existing bindings for the current device from the target action
var target_bindings = this.action_map[action_name]
for (var i = target_bindings.length - 1; i >= 0; i--) {
for (var i = length(target_bindings) - 1; i >= 0; i--) {
if (detect_device(target_bindings[i]) == this.current_device)
target_bindings.splice(i, 1)
}
@@ -281,11 +281,11 @@ action.get_bindings_for_device = function(action_name) {
// Returns the primary binding for display - prefer keyboard/mouse, then others
action.get_primary_binding = function(action_name) {
var all = this.action_map[action_name] || []
if (!all.length) return '(unbound)'
if (!length(all)) return '(unbound)'
// Prefer keyboard/mouse bindings for display stability (mouse buttons now detect as keyboard)
var keyboard = filter(all, function(id) { return detect_device(id) == 'keyboard' })
if (keyboard.length) return keyboard[0]
if (length(keyboard)) return keyboard[0]
// Fall back to any binding
return all[0]
@@ -294,7 +294,7 @@ action.get_primary_binding = function(action_name) {
// Returns the binding for the current device, or "Unbound!" if none
action.get_current_device_binding = function(action_name) {
var device_bindings = this.get_bindings_for_device(action_name)
if (!device_bindings.length) return 'Unbound!'
if (!length(device_bindings)) return 'Unbound!'
return device_bindings[0]
}

View File

@@ -51,8 +51,8 @@ function normalize_color(c, fallback) {
function normalize_spacing(s) {
if (is_number(s)) return {l:s, r:s, t:s, b:s}
if (is_array(s)) {
if (s.length == 2) return {l:s[0], r:s[0], t:s[1], b:s[1]}
if (s.length == 4) return {l:s[0], r:s[1], t:s[2], b:s[3]}
if (length(s) == 2) return {l:s[0], r:s[0], t:s[1], b:s[1]}
if (length(s) == 4) return {l:s[0], r:s[1], t:s[2], b:s[3]}
}
if (is_object(s)) return {l:s.l||0, r:s.r||0, t:s.t||0, b:s.b||0}
return {l:0, r:0, t:0, b:0}
@@ -204,7 +204,7 @@ function build_drawables(node, root_height, parent_abs_x, parent_abs_y, parent_s
// Children
for (var child of node.children) {
var child_drawables = build_drawables(child, root_height, vis_x, vis_y, current_scissor, parent_layer + 0.01)
for (var i = 0; i < child_drawables.length; i++) {
for (var i = 0; i < length(child_drawables); i++) {
drawables.push(child_drawables[i])
}
}
@@ -251,7 +251,7 @@ function push_node(configs, contain_mode) {
}
// Add to parent
var parent = tree_stack[tree_stack.length-1]
var parent = tree_stack[length(tree_stack)-1]
parent.children.push(node)
lay_ctx.insert(parent.id, item)

View File

@@ -34,11 +34,11 @@ function find_path(node, path, pos) {
if (!pointer_enabled(node)) return null
if (!rect_contains(node, pos)) return null
var next_path = path.concat(node)
var next_path = array(path, node)
if (node[clay.CHILDREN] && !should_skip_children(node)) {
// Children drawn later should be tested first; reverse if your render order differs
for (var i = node[clay.CHILDREN].length - 1; i >= 0; i--) {
for (var i = length(node[clay.CHILDREN]) - 1; i >= 0; i--) {
var child = node[clay.CHILDREN][i]
var child_path = find_path(child, next_path, pos)
if (child_path) return child_path
@@ -51,7 +51,7 @@ function find_path(node, path, pos) {
clay_input.deepest = function deepest(tree_root, pos) {
var path = find_path(tree_root, [], pos) || []
var deepest = path.length ? path[path.length - 1] : null
var deepest = length(path) ? path[length(path) - 1] : null
return deepest
}

View File

@@ -1,6 +1,6 @@
function tohex(n) {
var s = floor(n).toString(16);
if (s.length == 1) s = "0" + s;
if (length(s) == 1) s = "0" + s;
return upper(s);
};
@@ -101,7 +101,7 @@ Color.normalize = function (c) {
}
// Add alpha channel if not present
if (c[p].length == 3) {
if (length(c[p]) == 3) {
c[p][3] = 1;
}

View File

@@ -27,7 +27,7 @@ compositor.compile = function(config) {
// Process each plane (supports both 'planes' and legacy 'layers' key)
var planes = config.planes || config.layers || []
for (var i = 0; i < planes.length; i++) {
for (var i = 0; i < length(planes); i++) {
var plane = planes[i]
var type = plane.type || 'film2d'
if (type == 'imgui') {
@@ -58,7 +58,7 @@ function compile_plane(plane_config, ctx, group_effects) {
var mask_groups = {}
for (var gname in group_effects) {
var effects = group_effects[gname].effects || []
for (var e = 0; e < effects.length; e++) {
for (var e = 0; e < length(effects); e++) {
if (effects[e].type == 'mask' && effects[e].mask_group)
mask_groups[effects[e].mask_group] = true
}
@@ -69,7 +69,7 @@ function compile_plane(plane_config, ctx, group_effects) {
// Add manual drawables
if (plane_config.drawables) {
for (var i = 0; i < plane_config.drawables.length; i++)
for (var i = 0; i < length(plane_config.drawables); i++)
all_sprites.push(plane_config.drawables[i])
}
@@ -77,14 +77,14 @@ function compile_plane(plane_config, ctx, group_effects) {
var effect_groups = {} // group_name -> {sprites: [], effects: []}
var base_sprites = []
for (var i = 0; i < all_sprites.length; i++) {
for (var i = 0; i < length(all_sprites); i++) {
var s = all_sprites[i]
var sprite_groups = s.groups || []
var assigned = false
var is_mask_only = sprite_groups.length > 0
var is_mask_only = length(sprite_groups) > 0
// First pass: check if sprite has any non-mask group
for (var g = 0; g < sprite_groups.length; g++) {
for (var g = 0; g < length(sprite_groups); g++) {
var gname = sprite_groups[g]
if (!mask_groups[gname]) {
is_mask_only = false
@@ -93,7 +93,7 @@ function compile_plane(plane_config, ctx, group_effects) {
}
// Second pass: assign to effect groups
for (var g = 0; g < sprite_groups.length; g++) {
for (var g = 0; g < length(sprite_groups); g++) {
var gname = sprite_groups[g]
if (group_effects[gname]) {
if (!effect_groups[gname])
@@ -118,7 +118,7 @@ function compile_plane(plane_config, ctx, group_effects) {
// Render each effect group to temp target, apply effects, composite back
for (var gname in effect_groups) {
var eg = effect_groups[gname]
if (eg.sprites.length == 0) continue
if (length(eg.sprites) == 0) continue
var group_target = ctx.alloc(res.width, res.height, gname + '_content')
@@ -136,7 +136,7 @@ function compile_plane(plane_config, ctx, group_effects) {
// Apply effects
var current = group_target
for (var e = 0; e < eg.effects.length; e++) {
for (var e = 0; e < length(eg.effects); e++) {
var effect = eg.effects[e]
current = apply_effect(ctx, effect, current, res, camera, gname, plane_name, group_effects)
}
@@ -153,7 +153,7 @@ function compile_plane(plane_config, ctx, group_effects) {
}
// Render base sprites (no effects)
if (base_sprites.length > 0) {
if (length(base_sprites) > 0) {
ctx.passes.push({
type: 'render',
renderer: 'film2d',
@@ -210,7 +210,7 @@ function apply_effect(ctx, effect, input, size, camera, hint, current_plane, gro
// Query masks within the same plane to avoid cross-plane mask issues
var mask_sprites = film2d.query({group: mask_group, plane: current_plane})
if (mask_sprites.length > 0) {
if (length(mask_sprites) > 0) {
var mask_target = ctx.alloc(size.width, size.height, hint + '_mask')
// Render mask
@@ -262,7 +262,7 @@ compositor.execute = function(plan) {
var commands = []
for (var i = 0; i < plan.passes.length; i++) {
for (var i = 0; i < length(plan.passes); i++) {
var pass = plan.passes[i]
if (pass.type == 'clear') {
@@ -279,7 +279,7 @@ compositor.execute = function(plan) {
layer_sort: pass.layer_sort || {},
clear: pass.clear
}, backend)
for (var c = 0; c < result.commands.length; c++)
for (var c = 0; c < length(result.commands); c++)
commands.push(result.commands[c])
} else if (pass.type == 'shader_pass') {

View File

@@ -177,13 +177,13 @@ input.tabcomplete = function tabcomplete(val, list) {
if (!val) return val;
list = filter(list, x => starts_with(x, val))
if (list.length == 1) {
if (length(list) == 1) {
return list[0];
}
var ret = null;
var i = val.length;
while (!ret && list.length != 0) {
var i = length(val);
while (!ret && length(list) != 0) {
var char = list[0][i];
if (
!every(list, x => x[i] == char)
@@ -191,7 +191,7 @@ input.tabcomplete = function tabcomplete(val, list) {
ret = text(list[0], 0, i);
else {
i++;
list = filter(list, x => x.length-1 > i)
list = filter(list, x => length(x) - 1 > i)
}
}
@@ -301,7 +301,7 @@ var Player = {
n.pawns = {}
n.gamepads = [];
this.players.push(n);
this[this.players.length - 1] = n;
this[length(this.players) - 1] = n;
return n;
},

View File

@@ -195,14 +195,14 @@ function _main_loop() {
// Track FPS based on actual work time
_frame_time_ms = actual_frame_time * 1000
_fps_samples.push(actual_frame_time)
if (_fps_samples.length > _fps_sample_count) {
if (length(_fps_samples) > _fps_sample_count) {
_fps_samples.shift()
}
var avg_frame_time = 0
for (var i = 0; i < _fps_samples.length; i++) {
for (var i = 0; i < length(_fps_samples); i++) {
avg_frame_time += _fps_samples[i]
}
avg_frame_time = avg_frame_time / _fps_samples.length
avg_frame_time = avg_frame_time / length(_fps_samples)
_current_fps = avg_frame_time > 0 ? 1 / avg_frame_time : 0
// Schedule next frame

View File

@@ -116,7 +116,7 @@ function _render_node_tree(imgui, node, depth) {
label += " *"
}
var has_children = node.children && node.children.length > 0
var has_children = node.children && length(node.children) > 0
if (has_children) {
imgui.tree(label, function() {
@@ -124,7 +124,7 @@ function _render_node_tree(imgui, node, depth) {
_render_node_summary(imgui, node)
// Recurse children
for (var i = 0; i < node.children.length; i++) {
for (var i = 0; i < length(node.children); i++) {
_render_node_tree(imgui, node.children[i], depth + 1)
}
})
@@ -156,19 +156,19 @@ function _render_node_summary(imgui, node) {
if (node.text) {
var t = node.text
if (t.length > 20) t = text(t, 0, 17) + "..."
if (length(t) > 20) t = text(t, 0, 17) + "..."
info.push("\"" + t + "\"")
}
if (node.effects && node.effects.length > 0) {
if (node.effects && length(node.effects) > 0) {
var fx = []
for (var i = 0; i < node.effects.length; i++) {
for (var i = 0; i < length(node.effects); i++) {
fx.push(node.effects[i].type)
}
info.push("fx:[" + text(fx, ",") + "]")
}
if (info.length > 0) {
if (length(info) > 0) {
imgui.text(" " + text(info, " "))
}
}
@@ -242,10 +242,10 @@ function _render_node_inspector(imgui, node) {
}
// Effects
if (node.effects && node.effects.length > 0) {
if (node.effects && length(node.effects) > 0) {
imgui.text("---")
imgui.text("Effects:")
for (var i = 0; i < node.effects.length; i++) {
for (var i = 0; i < length(node.effects); i++) {
var fx = node.effects[i]
imgui.tree(fx.type, function() {
for (var k in fx) {
@@ -283,13 +283,13 @@ function _render_graph_view(imgui, plan) {
return
}
imgui.text("Passes: " + text(plan.passes.length))
imgui.text("Targets: " + text(array(plan.targets || {}).length))
imgui.text("Persistent: " + text(array(plan.persistent_targets || {}).length))
imgui.text("Passes: " + text(length(plan.passes)))
imgui.text("Targets: " + text(length(array(plan.targets || {}))))
imgui.text("Persistent: " + text(length(array(plan.persistent_targets || {}))))
imgui.text("---")
for (var i = 0; i < plan.passes.length; i++) {
for (var i = 0; i < length(plan.passes); i++) {
var pass = plan.passes[i]
var label = text(i) + ": " + pass.type
@@ -394,10 +394,10 @@ function _render_effects_panel(imgui) {
imgui.window("Effects Registry", function() {
var effect_list = effects_mod.list()
imgui.text("Registered effects: " + text(effect_list.length))
imgui.text("Registered effects: " + text(length(effect_list)))
imgui.text("---")
for (var i = 0; i < effect_list.length; i++) {
for (var i = 0; i < length(effect_list); i++) {
var name = effect_list[i]
var deff = effects_mod.get(name)

View File

@@ -33,7 +33,7 @@ action.on_input = function(action_id, action_data)
// Convert action_id to emacs key notation
var key = action_id
if (key.length == 1) {
if (length(key) == 1) {
// Single character keys
emacs_notation += lower(key)
} else {

View File

@@ -30,10 +30,10 @@ this.update = function(dt) {
// Compute FPS average over the last 60 frames:
var currentFPS = 1 / dt
fpsSamples.push(currentFPS)
if (fpsSamples.length > 60) fpsSamples.shift()
if (length(fpsSamples) > 60) fpsSamples.shift()
var sum = 0
for (var f of fpsSamples) sum += f
fpsAvg = sum / fpsSamples.length
fpsAvg = sum / length(fpsSamples)
// If left mouse is down, spawn some more bunnies:
var mouse = input.mousestate()
@@ -48,7 +48,7 @@ this.update = function(dt) {
}
// Update bunny positions and bounce them inside the screen:
for (var i = 0; i < bunnies.length; i++) {
for (var i = 0; i < length(bunnies); i++) {
var b = bunnies[i]
b.x += b.vx * dt
b.y += b.vy * dt
@@ -66,6 +66,6 @@ this.update = function(dt) {
this.hud = function() {
draw.images(bunnyTex, bunnies)
var msg = 'FPS: ' + fpsAvg.toFixed(2) + ' Bunnies: ' + bunnies.length
var msg = 'FPS: ' + fpsAvg.toFixed(2) + ' Bunnies: ' + length(bunnies)
draw.text(msg, {x:0, y:0, width:config.width, height:40}, null, 0, color.white, 0)
}

View File

@@ -76,7 +76,7 @@ function handleMouseButtonDown(e) {
if (!grid.inBounds(c)) return;
var cell = grid.at(c);
if (cell.length && cell[0].colour == mover.turn) {
if (length(cell) && cell[0].colour == mover.turn) {
selectPos = c;
holdingPiece = true;
// Send pickup notification to opponent
@@ -211,7 +211,7 @@ function isValidMoveForTurn(from, to) {
// Check if the destination has a piece of the same color
var destCell = grid.at(to);
if (destCell.length && destCell[0].colour == piece.colour) {
if (length(destCell) && destCell[0].colour == piece.colour) {
return false;
}
@@ -358,7 +358,7 @@ $receiver(e => {
log.console("Received move from opponent:", e.from, "to", e.to);
// Apply opponent's move
var fromCell = grid.at(e.from);
if (fromCell.length) {
if (length(fromCell)) {
var piece = fromCell[0];
if (mover.tryMove(piece, e.to)) {
isMyTurn = true; // It's now our turn

View File

@@ -32,7 +32,7 @@ grid.prototype = {
remove(entity, pos) {
def c = this.cell(pos.x, pos.y);
def i = search(c, entity);
if (i !== null) c.splice(i, 1);
if (i != null) c.splice(i, 1);
},
// bounds check
@@ -60,7 +60,7 @@ grid.prototype = {
var out = `grid [${this.width}×${this.height}]\n`;
for (var y = 0; y < this.height; y++) {
for (var x = 0; x < this.width; x++) {
out += this.cells[y][x].length;
out += length(this.cells[y][x]);
}
if (y != this.height - 1) out += "\n";
}

View File

@@ -15,8 +15,8 @@ MovementSystem.prototype.tryMove = function (piece, to) {
if (!this.rules.canMove(piece, piece.coord, dest, this.grid)) return false;
var victims = this.grid.at(dest);
if (victims.length && victims[0].colour == piece.colour) return false;
if (victims.length) victims[0].captured = true;
if (length(victims) && victims[0].colour == piece.colour) return false;
if (length(victims)) victims[0].captured = true;
this.grid.remove(piece, piece.coord);
this.grid.add (piece, dest);

View File

@@ -7,11 +7,11 @@ var deltas = {
pawn: function (pc, dx, dy, grid, to) {
var dir = (pc.colour == 'white') ? -1 : 1;
var base = (pc.colour == 'white') ? 6 : 1;
var one = (dy == dir && dx == 0 && grid.at(to).length == 0);
var one = (dy == dir && dx == 0 && length(grid.at(to)) == 0);
var two = (dy == 2 * dir && dx == 0 && cy(pc.coord) == base &&
grid.at({ x: cx(pc.coord), y: cy(pc.coord)+dir }).length == 0 &&
grid.at(to).length == 0);
var cap = (dy == dir && Math.abs(dx) == 1 && grid.at(to).length);
length(grid.at({ x: cx(pc.coord), y: cy(pc.coord)+dir })) == 0 &&
length(grid.at(to)) == 0);
var cap = (dy == dir && Math.abs(dx) == 1 && length(grid.at(to)));
return one || two || cap;
},
rook : function (pc, dx, dy) { return (dx == 0 || dy == 0); },
@@ -27,7 +27,7 @@ function clearLine(from, to, grid) {
var dy = Math.sign(cy(to) - cy(from));
var x = cx(from) + dx, y = cy(from) + dy;
while (x != cx(to) || y != cy(to)) {
if (grid.at({ x: x, y: y }).length) return false;
if (length(grid.at({ x: x, y: y }))) return false;
x += dx; y += dy;
}
return true;

View File

@@ -36,7 +36,7 @@ function resetGame() {
function spawnApple() {
apple = {x:floor(random.random()*gridW), y:floor(random.random()*gridH)}
// Re-spawn if apple lands on snake
for (var i=0; i<snake.length; i++)
for (var i=0; i<length(snake); i++)
if (snake[i].x == apple.x && snake[i].y == apple.y) { spawnApple(); return }
}
@@ -63,7 +63,7 @@ this.update = function(dt) {
wrap(head)
// Check collision with body
for (var i=0; i<snake.length; i++) {
for (var i=0; i<length(snake); i++) {
if (snake[i].x == head.x && snake[i].y == head.y) {
gameState = "gameover"
return
@@ -83,7 +83,7 @@ this.hud = function() {
draw.rectangle({x:0, y:0, width:config.width, height:config.height}, [0,0,0,1])
// Draw snake
for (var i=0; i<snake.length; i++) {
for (var i=0; i<length(snake); i++) {
var s = snake[i]
draw.rectangle({x:s.x*cellSize, y:s.y*cellSize, width:cellSize, height:cellSize}, color.green)
}

View File

@@ -65,7 +65,7 @@ function initBoard() {
initBoard()
function randomShape() {
var key = shapeKeys[floor(random.random()*shapeKeys.length)]
var key = shapeKeys[floor(random.random()*length(shapeKeys))]
// Make a copy of the shapes blocks
return {
type: key,
@@ -84,7 +84,7 @@ function spawnPiece() {
}
function collides(px, py, blocks) {
for (var i=0; i<blocks.length; i++) {
for (var i=0; i<length(blocks); i++) {
var x = px + blocks[i][0]
var y = py + blocks[i][1]
if (x<0 || x>=COLS || y<0 || y>=ROWS) return true
@@ -95,7 +95,7 @@ function collides(px, py, blocks) {
// Lock piece into board
function lockPiece() {
for (var i=0; i<piece.blocks.length; i++) {
for (var i=0; i<length(piece.blocks); i++) {
var x = pieceX + piece.blocks[i][0]
var y = pieceY + piece.blocks[i][1]
if (y>=0) board[y][x] = piece.color
@@ -105,7 +105,7 @@ function lockPiece() {
// Rotate 90° clockwise
function rotate(blocks) {
// (x,y) => (y,-x)
for (var i=0; i<blocks.length; i++) {
for (var i=0; i<length(blocks); i++) {
var x = blocks[i][0]
var y = blocks[i][1]
blocks[i][0] = y
@@ -242,7 +242,7 @@ this.hud = function() {
// Draw falling piece
if (!gameOver && piece) {
for (var i=0; i<piece.blocks.length; i++) {
for (var i=0; i<length(piece.blocks); i++) {
var x = pieceX + piece.blocks[i][0]
var y = pieceY + piece.blocks[i][1]
draw.rectangle({x:x*TILE, y:(ROWS-1-y)*TILE, width:TILE, height:TILE}, piece.color)
@@ -252,7 +252,7 @@ this.hud = function() {
// Next piece window
draw.text("Next", {x:70, y:5, width:50, height:10}, null, 0, color.white)
if (nextPiece) {
for (var i=0; i<nextPiece.blocks.length; i++) {
for (var i=0; i<length(nextPiece.blocks); i++) {
var nx = nextPiece.blocks[i][0]
var ny = nextPiece.blocks[i][1]
var dx = 12 + nx

View File

@@ -122,7 +122,7 @@ film2d.register = function(drawable) {
// Index by groups (effect routing only)
var groups = drawable.groups || []
for (var i = 0; i < groups.length; i++) {
for (var i = 0; i < length(groups); i++) {
var g = groups[i]
if (!group_index[g]) group_index[g] = []
group_index[g].push(id)
@@ -145,7 +145,7 @@ film2d.unregister = function(id) {
// Remove from group indices
var groups = drawable.groups || []
for (var i = 0; i < groups.length; i++) {
for (var i = 0; i < length(groups); i++) {
var g = groups[i]
if (group_index[g]) {
var idx = find(group_index[g], id_str)
@@ -169,9 +169,9 @@ film2d.unindex_group = function(id, group) {
}
film2d.reindex = function(id, old_groups, new_groups) {
for (var i = 0; i < old_groups.length; i++)
for (var i = 0; i < length(old_groups); i++)
film2d.unindex_group(id, old_groups[i])
for (var i = 0; i < new_groups.length; i++)
for (var i = 0; i < length(new_groups); i++)
film2d.index_group(id, new_groups[i])
}
@@ -186,7 +186,7 @@ film2d.query = function(selector) {
// Query by plane (primary selection)
if (selector.plane) {
var ids = plane_index[selector.plane] || []
for (var i = 0; i < ids.length; i++) {
for (var i = 0; i < length(ids); i++) {
var d = registry[ids[i]]
if (d && d.visible != false) {
// If also filtering by group, check membership
@@ -204,7 +204,7 @@ film2d.query = function(selector) {
// Query by group only (for effect routing)
if (selector.group) {
var ids = group_index[selector.group] || []
for (var i = 0; i < ids.length; i++) {
for (var i = 0; i < length(ids); i++) {
var d = registry[ids[i]]
if (d && d.visible != false) result.push(d)
}
@@ -213,9 +213,9 @@ film2d.query = function(selector) {
if (selector.groups) {
var seen = {}
for (var g = 0; g < selector.groups.length; g++) {
for (var g = 0; g < length(selector.groups); g++) {
var ids = group_index[selector.groups[g]] || []
for (var i = 0; i < ids.length; i++) {
for (var i = 0; i < length(ids); i++) {
if (!seen[ids[i]]) {
seen[ids[i]] = true
var d = registry[ids[i]]
@@ -244,7 +244,7 @@ film2d.get_groups = function(id) {
film2d.all_groups = function() {
var groups = []
for (var g in group_index)
if (group_index[g].length > 0) groups.push(g)
if (length(group_index[g]) > 0) groups.push(g)
return groups
}
@@ -259,7 +259,7 @@ film2d.render = function(params, render_backend) {
var clear_color = params.clear
var layer_sort = params.layer_sort || {} // layer(text) -> "y" or "explicit"
if (drawables.length == 0) return { commands: [] }
if (length(drawables) == 0) return { commands: [] }
function _y_sort_key(d) {
if (!d || !d.pos) return 0
@@ -275,7 +275,7 @@ film2d.render = function(params, render_backend) {
// Bucket drawables by layer
var buckets = Object.create(null) // layer_text -> array
for (var i = 0; i < drawables.length; i++) {
for (var i = 0; i < length(drawables); i++) {
var d = drawables[i]
var layer_key = String(d.layer || 0)
var b = buckets[layer_key]
@@ -295,7 +295,7 @@ film2d.render = function(params, render_backend) {
var y_down = camera && camera.y_down == true
var sorted_drawables = []
for (var li = 0; li < layers.length; li++) {
for (var li = 0; li < length(layers); li++) {
var layer_key = layers[li]
var b = buckets[layer_key]
@@ -306,7 +306,7 @@ film2d.render = function(params, render_backend) {
if (!y_down) b = reverse(b) // y_up => smaller y draws later => reverse
}
for (var j = 0; j < b.length; j++) sorted_drawables.push(b[j])
for (var j = 0; j < length(b); j++) sorted_drawables.push(b[j])
}
drawables = sorted_drawables
@@ -317,7 +317,7 @@ film2d.render = function(params, render_backend) {
var batches = _batch_drawables(drawables)
for (var i = 0; i < batches.length; i++) {
for (var i = 0; i < length(batches); i++) {
var batch = batches[i]
if (batch.type == "sprite_batch")
commands.push({ cmd: "draw_batch", batch_type: "sprites", geometry: { sprites: batch.sprites }, texture: batch.texture, material: batch.material })
@@ -340,7 +340,7 @@ function _batch_drawables(drawables) {
var current = null
var default_mat = {blend: 'alpha', sampler: 'nearest'}
for (var i = 0; i < drawables.length; i++) {
for (var i = 0; i < length(drawables); i++) {
var d = drawables[i]
if (d.type == 'sprite') {
@@ -364,7 +364,7 @@ function _batch_drawables(drawables) {
var emitter_opacity = d.opacity != null ? d.opacity : 1
var emitter_tint = d.tint || {r: 1, g: 1, b: 1, a: 1}
for (var p = 0; p < particles.length; p++) {
for (var p = 0; p < length(particles); p++) {
var part = particles[p]
var pc = part.color || {r: 1, g: 1, b: 1, a: 1}
var sprite = {
@@ -396,9 +396,9 @@ function _batch_drawables(drawables) {
var tilemap_opacity = d.opacity != null ? d.opacity : 1
var tilemap_tint = d.tint || {r: 1, g: 1, b: 1, a: 1}
for (var x = 0; x < tiles.length; x++) {
for (var x = 0; x < length(tiles); x++) {
if (!tiles[x]) continue
for (var y = 0; y < tiles[x].length; y++) {
for (var y = 0; y < length(tiles[x]); y++) {
var img = tiles[x][y]
if (!img) continue

View File

@@ -259,7 +259,7 @@ NODE_EXECUTORS.clip_rect = function(params, backend) {
// Insert scissor after begin_render
var insert_idx = 0
for (var i = 0; i < commands.length; i++) {
for (var i = 0; i < length(commands); i++) {
if (commands[i].cmd == 'begin_render') {
insert_idx = i + 1
break
@@ -269,7 +269,7 @@ NODE_EXECUTORS.clip_rect = function(params, backend) {
commands.splice(insert_idx, 0, {cmd: 'scissor', rect: rect})
// Add scissor reset before end_render
for (var i = commands.length - 1; i >= 0; i--) {
for (var i = length(commands) - 1; i >= 0; i--) {
if (commands[i].cmd == 'end_render') {
commands.splice(i, 0, {cmd: 'scissor', rect: null})
break

View File

@@ -32,7 +32,7 @@ gesture.on_input = function(action_id, action) {
startTime: time.number()
}
var touchCount = array(this.touches).length
var touchCount = length(array(this.touches))
if (touchCount == 1) {
// Single touch started
@@ -51,7 +51,7 @@ gesture.on_input = function(action_id, action) {
this.touches[fingerId].x = action.x
this.touches[fingerId].y = action.y
var touchCount = array(this.touches).length
var touchCount = length(array(this.touches))
if (touchCount == 2 && this.gestureState == 'multi') {
// Check for pinch gesture
@@ -70,7 +70,7 @@ gesture.on_input = function(action_id, action) {
else if (action_id == 'gamepad_touchpad_up') {
if (this.touches[fingerId]) {
var touch = this.touches[fingerId]
var touchCount = array(this.touches).length
var touchCount = length(array(this.touches))
// Check for swipe if this was the only/last touch
if (touchCount == 1 && this.gestureState == 'single') {
@@ -94,7 +94,7 @@ gesture.on_input = function(action_id, action) {
delete this.touches[fingerId]
// Reset if no touches left
if (array(this.touches).length == 0) {
if (length(array(this.touches)) == 0) {
this.gestureState = null
}
}

View File

@@ -163,7 +163,7 @@ function create_image(path){
/* ── Case B: array of surfaces (from make_gif) ────────────── */
if(is_array(raw)) {
// Single frame GIF returns array with one surface
if(raw.length == 1 && !raw[0].time) {
if(length(raw) == 1 && !raw[0].time) {
return new graphics.Image(raw[0])
}
// Multiple frames - create animation
@@ -184,7 +184,7 @@ function create_image(path){
else if(anim && anim.surface)
anims[name] = new graphics.Image(anim.surface);
}
if(array(anims).length) return anims;
if(length(array(anims))) return anims;
}
throw Error('Unsupported image structure from decoder');
@@ -340,7 +340,7 @@ graphics.texture = function texture(path) {
return anim
} else if (anim.frames && is_array(anim.frames)) {
// Multi-frame animation - wrap the index
idx = idx % anim.frames.length
idx = idx % length(anim.frames)
return anim.frames[idx].image
}
}
@@ -435,9 +435,9 @@ graphics.get_font = function get_font(path) {
graphics.queue_sprite_mesh = function(queue) {
var sprites = filter(queue, x => x.type == 'sprite')
if (sprites.length == 0) return []
if (length(sprites) == 0) return []
var mesh = graphics.make_sprite_mesh(sprites)
for (var i = 0; i < sprites.length; i++) {
for (var i = 0; i < length(sprites); i++) {
sprites[i].mesh = mesh
sprites[i].first_index = i*6
sprites[i].num_indices = 6

View File

@@ -100,7 +100,7 @@ function create_user(index, config) {
// Pop from control stack
pop: function() {
if (this.control_stack.length > 1) {
if (length(this.control_stack) > 1) {
return this.control_stack.pop()
}
return null
@@ -108,8 +108,8 @@ function create_user(index, config) {
// Get current control target
get target() {
return this.control_stack.length > 0
? this.control_stack[this.control_stack.length - 1]
return length(this.control_stack) > 0
? this.control_stack[length(this.control_stack) - 1]
: null
},
@@ -149,7 +149,7 @@ function create_user(index, config) {
// Pick user based on pairing policy
function pick_user(canon) {
if (_users.length == 0) return null
if (length(_users) == 0) return null
// For last_used: always user 0, just update active device
if (_config.pairing == 'last_used') {
@@ -177,7 +177,7 @@ function pick_user(canon) {
}
// For explicit pairing: find user paired to this device
for (var i = 0; i < _users.length; i++) {
for (var i = 0; i < length(_users); i++) {
if (find(_users[i].paired_devices, canon.device_id) != null) {
_users[i].active_device = canon.device_id
return _users[i]

View File

@@ -67,10 +67,10 @@ function make(defaults, display_names) {
// Get primary binding for display
bindings.get_primary_binding = function(action, device_kind) {
var device_bindings = this.get_bindings_for_device(action, device_kind)
if (device_bindings.length) return device_bindings[0]
if (length(device_bindings)) return device_bindings[0]
var all = this.action_map[action] || []
return all.length > 0 ? all[0] : null
return length(all) > 0 ? all[0] : null
}
// Get icon for action
@@ -146,7 +146,7 @@ function make(defaults, display_names) {
// Clear existing bindings for this device kind
var target = this.action_map[action]
for (var i = target.length - 1; i >= 0; i--) {
for (var i = length(target) - 1; i >= 0; i--) {
var existing_kind = starts_with(target[i], 'gamepad_') ? 'gamepad' :
starts_with(target[i], 'swipe_') ? 'touch' : 'keyboard'
if (existing_kind == device_kind) {

View File

@@ -35,7 +35,7 @@ function gesture_stage(config) {
process: function(events) {
var output = []
for (var i = 0; i < events.length; i++) {
for (var i = 0; i < length(events); i++) {
var ev = events[i]
// Only process gamepad touchpad events
@@ -53,7 +53,7 @@ function gesture_stage(config) {
startTime: time.number()
}
var count = Object.keys(touches).length
var count = length(array(touches))
if (count == 1) gesture_state = 'single'
else if (count == 2) {
gesture_state = 'multi'
@@ -65,7 +65,7 @@ function gesture_stage(config) {
if (touches[fingerId]) {
touches[fingerId].pos = ev.pos
var count = Object.keys(touches).length
var count = length(array(touches))
if (count == 2 && gesture_state == 'multi') {
var fingers = Object.values(touches)
var currentDist = dist(fingers[0].pos, fingers[1].pos)
@@ -89,7 +89,7 @@ function gesture_stage(config) {
else if (ev.released) {
if (touches[fingerId]) {
var touch = touches[fingerId]
var count = Object.keys(touches).length
var count = length(array(touches))
if (count == 1 && gesture_state == 'single') {
var dt = (time.number() - touch.startTime) * 1000
@@ -116,7 +116,7 @@ function gesture_stage(config) {
}
delete touches[fingerId]
if (Object.keys(touches).length == 0) gesture_state = null
if (length(array(touches)) == 0) gesture_state = null
}
}
}
@@ -134,7 +134,7 @@ function emacs_stage() {
process: function(events) {
var output = []
for (var i = 0; i < events.length; i++) {
for (var i = 0; i < length(events); i++) {
var ev = events[i]
// Only process keyboard button events
@@ -158,7 +158,7 @@ function emacs_stage() {
if (ev.mods?.ctrl) notation += "C-"
if (ev.mods?.alt) notation += "M-"
if (ev.control.length == 1) {
if (length(ev.control) == 1) {
notation += lower(ev.control)
} else {
notation += emacs_special[ev.control] || ev.control
@@ -208,7 +208,7 @@ function action_stage(bindings) {
process: function(events) {
var output = []
for (var i = 0; i < events.length; i++) {
for (var i = 0; i < length(events); i++) {
var ev = events[i]
// Pass through non-button events
@@ -219,12 +219,12 @@ function action_stage(bindings) {
var actions = bindings.get_actions(ev.control)
if (actions.length == 0) {
if (length(actions) == 0) {
output.push(ev)
continue
}
for (var j = 0; j < actions.length; j++) {
for (var j = 0; j < length(actions); j++) {
var action = actions[j]
if (ev.pressed) down[action] = true
@@ -251,7 +251,7 @@ function action_stage(bindings) {
function delivery_stage(user) {
return {
process: function(events) {
for (var i = 0; i < events.length; i++) {
for (var i = 0; i < length(events); i++) {
var ev = events[i]
// Only deliver actions
@@ -296,7 +296,7 @@ function make(user, config) {
handle: function(canon) {
var events = [canon]
for (var i = 0; i < this.stages.length; i++) {
for (var i = 0; i < length(this.stages); i++) {
events = this.stages[i].process(events)
}

View File

@@ -20,7 +20,7 @@ var line_proto = {
},
set_point: function(i, x, y) {
if (i >= 0 && i < this.points.length) {
if (i >= 0 && i < length(this.points)) {
this.points[i].x = x
this.points[i].y = y
this._dirty = true
@@ -58,7 +58,7 @@ var line_proto = {
function build_polyline_mesh(line) {
var points = line.points || []
if (points.length < 2) return {verts: [], indices: [], cumulative_lengths: [], total_length: 0}
if (length(points) < 2) return {verts: [], indices: [], cumulative_lengths: [], total_length: 0}
var width = line.width || 10
var widths = line.widths
@@ -78,7 +78,7 @@ function build_polyline_mesh(line) {
// Transform points if in local space
var pts = []
for (var i = 0; i < points.length; i++) {
for (var i = 0; i < length(points); i++) {
var p = points[i]
if (points_space == 'local') {
pts.push({x: p.x + pos.x, y: p.y + pos.y})
@@ -89,12 +89,12 @@ function build_polyline_mesh(line) {
// Calculate cumulative distances
var cumulative = [0]
for (var i = 1; i < pts.length; i++) {
for (var i = 1; i < length(pts); i++) {
var dx = pts[i].x - pts[i-1].x
var dy = pts[i].y - pts[i-1].y
cumulative.push(cumulative[i-1] + math.sqrt(dx*dx + dy*dy))
}
var total_length = cumulative[cumulative.length - 1]
var total_length = cumulative[length(cumulative) - 1]
// Build triangle strip mesh
var verts = []
@@ -102,7 +102,7 @@ function build_polyline_mesh(line) {
// Get width at point i
function get_width(i) {
if (widths && widths.length > i) return widths[i]
if (widths && length(widths) > i) return widths[i]
return width
}
@@ -123,10 +123,10 @@ function build_polyline_mesh(line) {
// Calculate normals at each point
var normals = []
for (var i = 0; i < pts.length; i++) {
var prev = i > 0 ? pts[i-1] : (closed ? pts[pts.length-1] : null)
for (var i = 0; i < length(pts); i++) {
var prev = i > 0 ? pts[i-1] : (closed ? pts[length(pts)-1] : null)
var curr = pts[i]
var next = i < pts.length-1 ? pts[i+1] : (closed ? pts[0] : null)
var next = i < length(pts)-1 ? pts[i+1] : (closed ? pts[0] : null)
var n = {x: 0, y: 0}
@@ -183,7 +183,7 @@ function build_polyline_mesh(line) {
}
// Generate vertices (2 per point - left and right of line)
for (var i = 0; i < pts.length; i++) {
for (var i = 0; i < length(pts); i++) {
var p = pts[i]
var n = normals[i]
var w = get_width(i) * 0.5
@@ -209,7 +209,7 @@ function build_polyline_mesh(line) {
}
// Generate indices (triangle strip as triangles)
for (var i = 0; i < pts.length - 1; i++) {
for (var i = 0; i < length(pts) - 1; i++) {
var base = i * 2
// First triangle
indices.push(base + 0)
@@ -222,8 +222,8 @@ function build_polyline_mesh(line) {
}
// Handle closed path
if (closed && pts.length > 2) {
var last = (pts.length - 1) * 2
if (closed && length(pts) > 2) {
var last = (length(pts) - 1) * 2
indices.push(last + 0)
indices.push(last + 1)
indices.push(0)
@@ -235,10 +235,10 @@ function build_polyline_mesh(line) {
// Add round caps if requested
if (!closed && cap == 'round') {
add_round_cap(verts, indices, pts[0], normals[0], get_width(0), get_u(0), v_offset, v_scale, true)
add_round_cap(verts, indices, pts[pts.length-1], normals[pts.length-1], get_width(pts.length-1), get_u(pts.length-1), v_offset, v_scale, false)
add_round_cap(verts, indices, pts[length(pts)-1], normals[length(pts)-1], get_width(length(pts)-1), get_u(length(pts)-1), v_offset, v_scale, false)
} else if (!closed && cap == 'square') {
add_square_cap(verts, indices, pts[0], normals[0], get_width(0), get_u(0), v_offset, v_scale, true, pts[1])
add_square_cap(verts, indices, pts[pts.length-1], normals[pts.length-1], get_width(pts.length-1), get_u(pts.length-1), v_offset, v_scale, false, pts[pts.length-2])
add_square_cap(verts, indices, pts[length(pts)-1], normals[length(pts)-1], get_width(length(pts)-1), get_u(length(pts)-1), v_offset, v_scale, false, pts[length(pts)-2])
}
return {
@@ -252,7 +252,7 @@ function build_polyline_mesh(line) {
function add_round_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_start) {
var w = width * 0.5
var segments = 8
var base_idx = verts.length
var base_idx = length(verts)
// Direction along the line
var dx = is_start ? -n.y : n.y
@@ -293,7 +293,7 @@ function add_round_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_sta
function add_square_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_start, adjacent) {
var w = width * 0.5
var base_idx = verts.length
var base_idx = length(verts)
// Direction along the line (away from adjacent point)
var dx = p.x - adjacent.x

View File

@@ -53,7 +53,7 @@ var emitters = {
}
// Update existing particles
for (var i = emitter.particles.length - 1; i >= 0; i--) {
for (var i = length(emitter.particles) - 1; i >= 0; i--) {
var p = emitter.particles[i]
p.time += dt
p.pos.x += p.velocity.x * dt

View File

@@ -165,7 +165,7 @@ PlaydateBackend.prototype.cmd_draw_batch = function(cmd) {
this.pd.graphics.setImageDrawMode(draw_mode)
// Draw each sprite in the batch
for (var i = 0; i < geometry.indices.length; i += 6) {
for (var i = 0; i < length(geometry.indices); i += 6) {
// Each sprite is 2 triangles = 6 indices = 4 vertices
var vert_idx = geometry.indices[i]
var v = geometry.vertices[vert_idx]
@@ -372,7 +372,7 @@ PlaydateBackend.prototype.gray_to_dither_pattern = function(gray) {
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
]
var index = floor(gray * (patterns.length - 1))
var index = floor(gray * (length(patterns) - 1))
return patterns[index]
}

View File

@@ -51,7 +51,7 @@ function find_in_path(filename, exts = []) {
}
// Only check extensions if exts is provided and not empty
if (exts.length > 0) {
if (length(exts) > 0) {
for (var ext of exts) {
var candidate = filename + '.' + ext
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
@@ -124,7 +124,7 @@ Resources.getAllFiles = function(dir = "") {
// Categorize files by resource type
Resources.gatherStats = function(filePaths) {
var stats = {
scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:filePaths.length
scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:length(filePaths)
}
for (var path of filePaths) {
var ext = getExtension(path)

View File

@@ -715,14 +715,14 @@ function _load_image_file(path) {
break
case 'gif':
decoded = gif.decode(bytes)
if (decoded && decoded.frames && decoded.frames.length > 0) {
if (decoded && decoded.frames && length(decoded.frames) > 0) {
surface = decoded.frames[0]
}
break
case 'ase':
case 'aseprite':
decoded = aseprite.decode(bytes)
if (decoded && decoded.frames && decoded.frames.length > 0) {
if (decoded && decoded.frames && length(decoded.frames) > 0) {
surface = decoded.frames[0]
}
break
@@ -844,14 +844,14 @@ function _build_sprite_vertices(sprites, camera) {
var vertices_per_sprite = 4
var indices_per_sprite = 6
var vertex_data = blob_mod(sprites.length * vertices_per_sprite * floats_per_vertex * 4)
var index_data = blob_mod(sprites.length * indices_per_sprite * 2)
var vertex_data = blob_mod(length(sprites) * vertices_per_sprite * floats_per_vertex * 4)
var index_data = blob_mod(length(sprites) * indices_per_sprite * 2)
var vertex_count = 0
var white = {r: 1, g: 1, b: 1, a: 1}
for(var i = 0; i < sprites.length; i++) {
for(var i = 0; i < length(sprites); i++) {
var s = sprites[i]
var px = s.pos.x
var py = s.pos.y
@@ -962,7 +962,7 @@ function _build_sprite_vertices(sprites, camera) {
vertices: stone(vertex_data),
indices: stone(index_data),
vertex_count: vertex_count,
index_count: sprites.length * 6
index_count: length(sprites) * 6
}
}
@@ -1152,7 +1152,7 @@ function _execute_commands(commands, window_size) {
switch (cmd.cmd) {
case 'begin_render':
// Flush pending draws
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1223,7 +1223,7 @@ function _execute_commands(commands, window_size) {
case 'blit':
// Flush pending draws first
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1239,7 +1239,7 @@ function _execute_commands(commands, window_size) {
case 'apply_mask':
// Flush pending draws first
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1255,7 +1255,7 @@ function _execute_commands(commands, window_size) {
case 'shader_pass':
// Flush pending draws first
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1271,7 +1271,7 @@ function _execute_commands(commands, window_size) {
case 'composite_textures':
// Flush pending draws first
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1287,7 +1287,7 @@ function _execute_commands(commands, window_size) {
case 'end_render':
// Flush pending draws
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1300,7 +1300,7 @@ function _execute_commands(commands, window_size) {
case 'imgui':
// Flush pending draws first
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
pending_draws = []
}
@@ -1355,7 +1355,7 @@ function _execute_commands(commands, window_size) {
}
// Final flush
if (current_pass && pending_draws.length > 0) {
if (current_pass && length(pending_draws) > 0) {
_flush_draws(cmd_buffer, current_pass, pending_draws, current_camera, current_target)
}
@@ -1446,14 +1446,14 @@ function _flush_draws(cmd_buffer, pass, draws, camera, target) {
function _render_batch(cmd_buffer, pass, batch, camera, target) {
if (batch.type == 'sprites') {
if (batch.sprites.length == 0) return
if (length(batch.sprites) == 0) return
var tex = batch.texture_path == '_white' ? _white_texture : sdl_gpu.get_texture(batch.texture_path)
var geom = _build_sprite_vertices(batch.sprites, camera)
// Upload geometry
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})
@@ -1514,8 +1514,8 @@ function _render_texture_ref(cmd_buffer, pass, drawable, camera, target) {
var geom = _build_sprite_vertices(sprites, camera)
// Upload geometry
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})
@@ -1695,7 +1695,7 @@ function _render_shape(cmd_buffer, pass, drawable, camera, target) {
function _render_mesh2d(cmd_buffer, pass, draw, camera, target) {
var meshes = draw.meshes || []
if (meshes.length == 0) return
if (length(meshes) == 0) return
var tex_path = draw.texture
var tex = tex_path ? sdl_gpu.get_texture(tex_path) : _white_texture
@@ -1706,8 +1706,8 @@ function _render_mesh2d(cmd_buffer, pass, draw, camera, target) {
var total_verts = 0
var total_indices = 0
for (var m of meshes) {
if (m.verts) total_verts += m.verts.length
if (m.indices) total_indices += m.indices.length
if (m.verts) total_verts += length(m.verts)
if (m.indices) total_indices += length(m.indices)
}
if (total_verts == 0 || total_indices == 0) return
@@ -1745,7 +1745,7 @@ function _render_mesh2d(cmd_buffer, pass, draw, camera, target) {
index_data.w16(vertex_offset + idx)
}
vertex_offset += verts.length
vertex_offset += length(verts)
}
// Upload geometry
@@ -2012,8 +2012,8 @@ function _do_blit(cmd_buffer, cmd, current_target, get_swapchain_tex) {
}
function _draw_textured_quad(pass, geom, texture, pipeline, filter) {
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})
@@ -2067,8 +2067,8 @@ function _do_mask(cmd_buffer, cmd) {
// Build fullscreen quad
var geom = _build_fullscreen_quad({x: 0, y: 0, width: output.width, height: output.height}, output.width, output.height)
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})
@@ -2159,8 +2159,8 @@ function _do_shader_pass(cmd_buffer, cmd, get_swapchain_tex) {
var geom = _build_fullscreen_quad({x: 0, y: 0, width: out_w, height: out_h}, out_w, out_h)
// Upload geometry
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})
@@ -2298,8 +2298,8 @@ function _do_composite(cmd_buffer, cmd) {
// Build fullscreen quad
var geom = _build_fullscreen_quad({x: 0, y: 0, width: output.width, height: output.height}, output.width, output.height)
var vb_size = geom.vertices.length / 8
var ib_size = geom.indices.length / 8
var vb_size = length(geom.vertices) / 8
var ib_size = length(geom.indices) / 8
var vb = new gpu_mod.buffer(_gpu, {size: vb_size, vertex: true})
var ib = new gpu_mod.buffer(_gpu, {size: ib_size, index: true})

View File

@@ -21,9 +21,9 @@ var Anim = (() => {
a.timer -= time;
a.idx += 1;
if(a.idx >= frames.length){
if(a.idx >= length(frames)){
if(a.loop) a.idx = 0;
else { a.idx = frames.length - 1; a.timer = 0; break; }
else { a.idx = length(frames) - 1; a.timer = 0; break; }
}
}
}

View File

@@ -89,12 +89,12 @@ function loop()
dt = os.now() - now
fps_samples.push(dt)
if (fps_samples.length > fps_window) fps_samples.shift()
if (length(fps_samples) > fps_window) fps_samples.shift()
if (now - last_fps_update >= fps_update_period) {
var sum = 0
arrfor(fps_samples, x => sum += x)
prosperon.window.title = `Bunnymark [fps: ${(fps_samples.length/sum).toFixed(1)}]`;
prosperon.window.title = `Bunnymark [fps: ${(length(fps_samples)/sum).toFixed(1)}]`;
last_fps_update = now
}

View File

@@ -4,7 +4,7 @@ var json = use('json');
// Get list of cameras
var cameras = camera.list();
if (cameras.length == 0) {
if (length(cameras) == 0) {
log.console("No cameras found!");
$stop();
}
@@ -18,7 +18,7 @@ log.console("\nLooking for different colorspaces in supported formats...");
// Group formats by colorspace
var colorspaces = {};
for (var i = 0; i < formats.length; i++) {
for (var i = 0; i < length(formats); i++) {
var fmt = formats[i];
if (!colorspaces[fmt.colorspace]) {
colorspaces[fmt.colorspace] = [];
@@ -28,7 +28,7 @@ for (var i = 0; i < formats.length; i++) {
log.console("\nFound colorspaces:");
for (var cs in colorspaces) {
log.console(" " + cs + ": " + colorspaces[cs].length + " formats");
log.console(" " + cs + ": " + length(colorspaces[cs]) + " formats");
}
// Try opening camera with different colorspaces

View File

@@ -5,7 +5,7 @@ var json = use('json');
// Get first camera
var cameras = camera.list();
if (cameras.length == 0) {
if (length(cameras) == 0) {
log.console("No cameras found!");
$stop();
}

View File

@@ -7,10 +7,10 @@ log.console("Available camera drivers:", drivers);
// Get list of cameras
var cameras = camera.list();
log.console("Found", cameras.length, "cameras");
log.console("Found", length(cameras), "cameras");
// Get info about each camera
for (var i = 0; i < cameras.length; i++) {
for (var i = 0; i < length(cameras); i++) {
var cam_id = cameras[i];
log.console("\nCamera", i + 1, "ID:", cam_id);
log.console(" Name:", camera.name(cam_id));
@@ -18,10 +18,10 @@ for (var i = 0; i < cameras.length; i++) {
// Get supported formats
var formats = camera.supported_formats(cam_id);
log.console(" Supported formats:", formats.length);
log.console(" Supported formats:", length(formats));
// Show first few formats
for (var j = 0; j < formats.length; j++) {
for (var j = 0; j < length(formats); j++) {
var fmt = formats[j];
log.console(" Format", j + 1 + ":");
log.console(" Pixel format:", fmt.format);
@@ -33,14 +33,14 @@ for (var i = 0; i < cameras.length; i++) {
}
// Open the first camera with a specific format if available
if (cameras.length > 0) {
if (length(cameras) > 0) {
log.console("\nOpening first camera...");
var cam_id = cameras[0];
var formats = camera.supported_formats(cam_id);
// Try to find a 640x480 format
var preferred_format = null;
for (var i = 0; i < formats.length; i++) {
for (var i = 0; i < length(formats); i++) {
if (formats[i].width == 640 && formats[i].height == 480) {
preferred_format = formats[i];
break;

View File

@@ -31,7 +31,7 @@ var colorspaces = ["srgb", "srgb_linear", "jpeg", "bt601_limited", "bt709_limite
var test_format = "rgba8888";
log.console("\nTest 3: Converting to", test_format, "with different colorspaces:");
for (var i = 0; i < colorspaces.length; i++) {
for (var i = 0; i < length(colorspaces); i++) {
try {
var conv = surf.convert(test_format, colorspaces[i]);
log.console(" " + colorspaces[i] + ": Success");
@@ -49,7 +49,7 @@ var yuv_tests = [
{format: "yvyu", colorspace: "bt601_full"}
];
for (var i = 0; i < yuv_tests.length; i++) {
for (var i = 0; i < length(yuv_tests); i++) {
var test = yuv_tests[i];
try {
var conv = surf.convert(test.format, test.colorspace);

View File

@@ -67,14 +67,14 @@ send(video_actor, {
// List available cameras
var cameras = camera.list();
if (cameras.length == 0) {
if (length(cameras) == 0) {
log.error("No cameras found!");
log.console(cameras)
$stop();
return;
}
log.console("Found", cameras.length, "camera(s)");
log.console("Found", length(cameras), "camera(s)");
// Open the first camera
cam_id = cameras[0];
@@ -84,11 +84,11 @@ send(video_actor, {
// Get supported formats and try to find a good one
var formats = camera.supported_formats(cam_id);
log.console("Camera supports", formats.length, "formats");
log.console("Camera supports", length(formats), "formats");
// Look for a 640x480 format with preferred colorspace
var preferred_format = null;
for (var i = 0; i < formats.length; i++) {
for (var i = 0; i < length(formats); i++) {
if (formats[i].width == 640 && formats[i].height == 480) {
preferred_format = formats[i];
// Prefer JPEG or sRGB colorspace if available
@@ -98,7 +98,7 @@ send(video_actor, {
}
}
if (!preferred_format && formats.length > 0) {
if (!preferred_format && length(formats) > 0) {
// Use first available format
preferred_format = formats[0];
}

View File

@@ -18,10 +18,10 @@ var tilemap = {
var x = pos.x - this.offset_x
var y = pos.y - this.offset_y
while (this.tiles.length <= x)
while (length(this.tiles) <= x)
this.tiles.push([])
while (this.tiles[x].length <= y)
while (length(this.tiles[x]) <= y)
this.tiles[x].push(null)
this.tiles[x][y] = image