Разделить частоту обновления часов и расчёта симуляции
Счётчик времени UI обновляется до 10 Гц по запрошенному времени, а тяжёлые циклы по-прежнему запускаются с адаптивным интервалом и обрабатывают весь накопленный промежуток. Обновить тесты и описание модели.
This commit is contained in:
@@ -69,7 +69,9 @@ func coarsen_cycle_stars(target: Dictionary, id: String) -> void:
|
||||
func temporal_resolution(target: Dictionary) -> Variant:
|
||||
var speed: int = int(target.get("speed", 1))
|
||||
if speed < 4: return 0
|
||||
var width: Variant = E.divide(E.power(10, speed - 1), 10)
|
||||
# Keep the existing 0.1-second resolution at the default 5 Hz cadence,
|
||||
# and scale temporal grouping with the adaptive cycle interval.
|
||||
var width: Variant = E.multiply(E.power(10, speed - 1), world.frame_step_seconds / 2.0)
|
||||
return E.multiply(width, E.power(2, world.adaptive_quality))
|
||||
|
||||
func window_duration(target: Dictionary, lifespan: Variant) -> Variant:
|
||||
|
||||
@@ -23,6 +23,12 @@ var adaptive_quality: int = 0
|
||||
var adaptive_cycle_ema_ms: float = 0.0
|
||||
var adaptive_recovery_cycles: int = 0
|
||||
var adaptive_generation_phase: int = 0
|
||||
## Runtime-only cadence: 5, 4, 3, or 2 full simulation cycles per second.
|
||||
var adaptive_cadence: bool = true
|
||||
var cadence_level: int = 0
|
||||
var cadence_recovery_cycles: int = 0
|
||||
const CADENCE_STEPS: Array[float] = [0.2, 0.25, 1.0 / 3.0, 0.5]
|
||||
var frame_step_seconds: float = 0.2
|
||||
|
||||
func update_adaptive_quality(cycle_usec: int) -> void:
|
||||
var cycle_ms: float = float(cycle_usec) / 1000.0
|
||||
@@ -46,6 +52,20 @@ func update_adaptive_quality(cycle_usec: int) -> void:
|
||||
adaptive_recovery_cycles = 0
|
||||
else:
|
||||
adaptive_recovery_cycles = 0
|
||||
if adaptive_cadence:
|
||||
var step: float = CADENCE_STEPS[cadence_level]
|
||||
if adaptive_cycle_ema_ms > step * 900.0 and cadence_level < CADENCE_STEPS.size() - 1:
|
||||
cadence_level += 1
|
||||
frame_step_seconds = CADENCE_STEPS[cadence_level]
|
||||
cadence_recovery_cycles = 0
|
||||
elif adaptive_cycle_ema_ms < step * 650.0 and cadence_level > 0:
|
||||
cadence_recovery_cycles += 1
|
||||
if cadence_recovery_cycles >= 30:
|
||||
cadence_level -= 1
|
||||
frame_step_seconds = CADENCE_STEPS[cadence_level]
|
||||
cadence_recovery_cycles = 0
|
||||
else:
|
||||
cadence_recovery_cycles = 0
|
||||
if adaptive_quality >= 3:
|
||||
adaptive_generation_phase = 1 - adaptive_generation_phase
|
||||
|
||||
@@ -103,9 +123,12 @@ var _production_queue_cancelled: bool = false
|
||||
var frame_active_clock: Dictionary = {}
|
||||
var _resume_clock: Dictionary = {}
|
||||
var frame_elapsed_seconds: float = 0.0
|
||||
const frame_step_seconds: float = 0.2
|
||||
const production_slice_usec: int = 4000
|
||||
|
||||
## The HUD follows requested time; world state remains at the last committed cycle.
|
||||
func display_clock() -> Dictionary:
|
||||
return frame_clock if not frame_clock.is_empty() else state.time
|
||||
|
||||
## Keep the requested clock advancing while a transaction spans render frames.
|
||||
func evolute_frame(delta: float, tree: SceneTree) -> void:
|
||||
if not is_finite(delta) or delta < 0.0 or not is_finite(delta * pow(10.0, speed - 1)): return
|
||||
|
||||
Reference in New Issue
Block a user