y
This commit is contained in:
parent
61718e2981
commit
f657b6a4a4
94 changed files with 3970 additions and 1241 deletions
|
|
@ -17,28 +17,34 @@
|
|||
for (let i = 0; i < effects.length; i += 1) {
|
||||
const effect = effects[i];
|
||||
if (effect && !effect.dead) effects[write++] = effect;
|
||||
else if (effect) worldRef.releaseEffect?.(effect);
|
||||
}
|
||||
effects.length = write;
|
||||
const compacted = before - write;
|
||||
const cap = Math.max(1, Number(global.TarinaiPerf?.performanceProfile?.().effectCap || 220));
|
||||
if (effects.length <= cap) return { compacted, dropped: 0 };
|
||||
let needDrop = Math.max(0, effects.length - cap);
|
||||
if (!needDrop) return { compacted, dropped: 0 };
|
||||
|
||||
const drop = effects
|
||||
.map((effect, index) => ({
|
||||
effect,
|
||||
index,
|
||||
score: effectPriority(effect) * 10 + Math.max(0, Math.min(1, Number(effect.life || 0) / Math.max(0.001, Number(effect.maxLife || effect.life || 1)))),
|
||||
}))
|
||||
.sort((a, b) => a.score - b.score)
|
||||
.slice(0, effects.length - cap);
|
||||
const dropSet = new Set(drop.map(entry => entry.index));
|
||||
const dropMask = new Uint8Array(effects.length);
|
||||
for (let priority = 1; priority <= 3 && needDrop > 0; priority += 1) {
|
||||
for (let i = 0; i < effects.length && needDrop > 0; i += 1) {
|
||||
if (dropMask[i] || effectPriority(effects[i]) !== priority) continue;
|
||||
dropMask[i] = 1;
|
||||
needDrop -= 1;
|
||||
}
|
||||
}
|
||||
write = 0;
|
||||
let dropped = 0;
|
||||
for (let i = 0; i < effects.length; i += 1) {
|
||||
if (!dropSet.has(i)) effects[write++] = effects[i];
|
||||
const effect = effects[i];
|
||||
if (dropMask[i]) {
|
||||
dropped += 1;
|
||||
worldRef.releaseEffect?.(effect);
|
||||
} else effects[write++] = effect;
|
||||
}
|
||||
effects.length = write;
|
||||
worldRef._effectPressureDroppedTotal = (worldRef._effectPressureDroppedTotal || 0) + dropSet.size;
|
||||
return { compacted, dropped: dropSet.size };
|
||||
worldRef._effectPressureDroppedTotal = (worldRef._effectPressureDroppedTotal || 0) + dropped;
|
||||
return { compacted, dropped };
|
||||
}
|
||||
|
||||
function effectUpdateBudgetFor(total) {
|
||||
|
|
@ -61,37 +67,54 @@
|
|||
const total = effects.length;
|
||||
const frameId = (worldRef._effectUpdateFrameId || 0) + 1;
|
||||
worldRef._effectUpdateFrameId = frameId;
|
||||
const budget = effectUpdateBudgetFor(total);
|
||||
if (budget >= total) {
|
||||
for (const ef of effects) updateEffect(ef, dt, frameId, 1);
|
||||
worldRef._effectUpdateStats = { total, beforePressure, updated: total, skipped: 0, budget: total, compacted: pressure.compacted, dropped: pressure.dropped, batched: false };
|
||||
return;
|
||||
|
||||
let lightweight = 0;
|
||||
const budgeted = [];
|
||||
for (const effect of effects) {
|
||||
if (!effect || effect.dead) continue;
|
||||
if (effect.type === "ring") {
|
||||
effect.life -= dt;
|
||||
effect._effectUpdatedFrame = frameId;
|
||||
lightweight += 1;
|
||||
} else {
|
||||
budgeted.push(effect);
|
||||
}
|
||||
}
|
||||
const runScale = Math.min(3.0, Math.max(1, total / Math.max(1, budget)));
|
||||
let cursor = Math.max(0, Math.floor(worldRef._effectUpdateCursor || 0)) % total;
|
||||
|
||||
const active = budgeted.length;
|
||||
const budget = effectUpdateBudgetFor(active);
|
||||
let updated = 0;
|
||||
let scanned = 0;
|
||||
while (updated < budget && scanned < total) {
|
||||
const ef = effects[cursor];
|
||||
cursor = (cursor + 1) % total;
|
||||
scanned += 1;
|
||||
if (!ef || ef.dead) continue;
|
||||
updateEffect(ef, dt, frameId, runScale);
|
||||
updated += 1;
|
||||
let runScale = 1;
|
||||
if (budget >= active) {
|
||||
for (const ef of budgeted) {
|
||||
if (updateEffect(ef, dt, frameId, 1)) updated += 1;
|
||||
}
|
||||
} else if (active > 0) {
|
||||
runScale = Math.min(3.0, Math.max(1, active / Math.max(1, budget)));
|
||||
let cursor = Math.max(0, Math.floor(worldRef._effectUpdateCursor || 0)) % active;
|
||||
let scanned = 0;
|
||||
while (updated < budget && scanned < active) {
|
||||
const ef = budgeted[cursor];
|
||||
cursor = (cursor + 1) % active;
|
||||
scanned += 1;
|
||||
if (!ef || ef.dead) continue;
|
||||
updateEffect(ef, dt, frameId, runScale);
|
||||
updated += 1;
|
||||
}
|
||||
worldRef._effectUpdateCursor = cursor;
|
||||
}
|
||||
worldRef._effectUpdateCursor = cursor;
|
||||
worldRef._effectUpdateStats = {
|
||||
total,
|
||||
beforePressure,
|
||||
updated,
|
||||
skipped: Math.max(0, total - updated),
|
||||
budget,
|
||||
runScale: Number(runScale.toFixed(2)),
|
||||
compacted: pressure.compacted,
|
||||
dropped: pressure.dropped,
|
||||
droppedTotal: worldRef._effectPressureDroppedTotal || 0,
|
||||
batched: true,
|
||||
};
|
||||
|
||||
if (global.TarinaiPerf?.diagnosticsEnabled?.() === true) {
|
||||
const spawn = worldRef._effectSpawnStats || {};
|
||||
worldRef._effectUpdateStats = {
|
||||
total, beforePressure, updated: updated + lightweight, lightweight,
|
||||
skipped: Math.max(0, active - updated), budget,
|
||||
runScale: Number(runScale.toFixed(2)), compacted: pressure.compacted, dropped: pressure.dropped,
|
||||
droppedTotal: worldRef._effectPressureDroppedTotal || 0, batched: budget < active,
|
||||
spawnRequested: spawn.requested || 0, offscreenCulled: spawn.offscreenCulled || 0,
|
||||
poolEligible: spawn.poolEligible || 0, pooled: spawn.pooled || 0,
|
||||
};
|
||||
} else worldRef._effectUpdateStats = null;
|
||||
}
|
||||
|
||||
global.TarinaiEffectsSimulationSystem = Object.freeze({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue