pub struct BudgetController { /* private fields */ }Expand description
Adaptive budget controller combining PID regulation with e-process gating.
§Architecture
frame_time ─┬─► PID Controller ─► control signal u_t
│ │
└─► E-Process ──────► gate ────┤
▼
Decision Logic
┌───────────────┐
│ u_t > thresh │──► DEGRADE (if e-process permits)
│ u_t < -thresh │──► UPGRADE (if e-process permits)
│ otherwise │──► HOLD
└───────────────┘The PID controller provides smooth, reactive adaptation. The e-process gates decisions to ensure statistical validity — we only degrade when there is strong evidence of sustained overload, not just transient spikes.
§Usage
use ftui_render::budget::{BudgetController, BudgetControllerConfig, DegradationLevel};
use std::time::Duration;
let mut controller = BudgetController::new(BudgetControllerConfig::default());
// After each frame, feed the observed frame time:
let decision = controller.update(Duration::from_millis(20)); // slow frame
// decision tells you what to do: Hold, Degrade, or UpgradeImplementations§
Source§impl BudgetController
impl BudgetController
Sourcepub fn new(config: BudgetControllerConfig) -> Self
pub fn new(config: BudgetControllerConfig) -> Self
Create a new budget controller with the given configuration.
Sourcepub fn update(&mut self, frame_time: Duration) -> BudgetDecision
pub fn update(&mut self, frame_time: Duration) -> BudgetDecision
Feed a frame time observation and get a decision.
Call this once per frame with the measured frame duration.
Sourcepub fn level(&self) -> DegradationLevel
pub fn level(&self) -> DegradationLevel
Get the current degradation level.
Sourcepub fn sync_level(&mut self, level: DegradationLevel)
pub fn sync_level(&mut self, level: DegradationLevel)
Synchronize the controller’s level with an externally applied change.
RenderBudget calls this whenever its degradation level is mutated
outside the controller’s own decision (guardrail emergencies, the
conformal risk gate, manual set_degradation). Without it the
controller keeps reasoning from a stale level: believing it is at
Full it reports AtFullQuality and holds forever, so an externally
degraded UI never recovers, and its floor clamp computes from the
wrong base. Starts a cooldown window, since a transition just
happened.
Sourcepub fn eprocess_sigma_ms(&self) -> f64
pub fn eprocess_sigma_ms(&self) -> f64
Get the current e-process sigma estimate (ms).
Sourcepub fn pid_integral(&self) -> f64
pub fn pid_integral(&self) -> f64
Get the current PID integral term (for diagnostics/logging).
Sourcepub fn frames_observed(&self) -> u32
pub fn frames_observed(&self) -> u32
Get the number of frames observed by the e-process.
Sourcepub fn telemetry(&self) -> BudgetTelemetry
pub fn telemetry(&self) -> BudgetTelemetry
Capture a telemetry snapshot of the controller state.
This is allocation-free and suitable for calling every frame. Forward the result to a debug overlay or structured logger.
Sourcepub fn config(&self) -> &BudgetControllerConfig
pub fn config(&self) -> &BudgetControllerConfig
Get a reference to the controller configuration.
Trait Implementations§
Source§impl Clone for BudgetController
impl Clone for BudgetController
Source§fn clone(&self) -> BudgetController
fn clone(&self) -> BudgetController
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more