Skip to main content

BudgetController

Struct BudgetController 

Source
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 Upgrade

Implementations§

Source§

impl BudgetController

Source

pub fn new(config: BudgetControllerConfig) -> Self

Create a new budget controller with the given configuration.

Source

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.

Source

pub fn level(&self) -> DegradationLevel

Get the current degradation level.

Source

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.

Source

pub fn e_value(&self) -> f64

Get the current e-process value (for diagnostics/logging).

Source

pub fn eprocess_sigma_ms(&self) -> f64

Get the current e-process sigma estimate (ms).

Source

pub fn pid_integral(&self) -> f64

Get the current PID integral term (for diagnostics/logging).

Source

pub fn frames_observed(&self) -> u32

Get the number of frames observed by the e-process.

Source

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.

Source

pub fn reset(&mut self)

Reset the controller to initial state.

Source

pub fn config(&self) -> &BudgetControllerConfig

Get a reference to the controller configuration.

Trait Implementations§

Source§

impl Clone for BudgetController

Source§

fn clone(&self) -> BudgetController

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BudgetController

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.