Expand description
Measure cache for memoizing widget measure results.
Measure cache for memoizing widget measure() results.
This module provides MeasureCache which caches SizeConstraints returned by
MeasurableWidget::measure() to avoid redundant computation during layout passes.
§Overview
During a single layout pass, the same widget may be queried multiple times with the same available size. Complex widgets like Tables with many cells can be expensive to measure. The cache eliminates this redundancy.
§Usage
use ftui_core::geometry::Size;
use ftui_widgets::{MeasureCache, WidgetId, SizeConstraints};
let mut cache = MeasureCache::new(100);
// First call computes the value
let constraints = cache.get_or_compute(
WidgetId::from_ptr(&my_widget),
Size::new(80, 24),
|| my_widget.measure(Size::new(80, 24)),
);
// Second call with same key returns cached value
let cached = cache.get_or_compute(
WidgetId::from_ptr(&my_widget),
Size::new(80, 24),
|| SizeConstraints::default(),
);§Invalidation Strategies
§Generation-Based (Primary)
Call MeasureCache::invalidate_all() after any state change affecting layout:
match msg {
Msg::DataChanged(data) => {
self.data = data;
self.measure_cache.invalidate_all();
}
Msg::Resize(_) => {
// Size is part of cache key, no invalidation needed!
}
}§Widget-Specific Invalidation
When only one widget’s content changes:
match msg {
Msg::ListItemAdded(item) => {
self.list.push(item);
self.measure_cache.invalidate_widget(WidgetId::from_hash(&"list"));
}
}§Content-Addressed (Automatic)
Use content hash as widget ID for automatic invalidation:
impl MeasurableWidget for Paragraph<'_> {
fn widget_id(&self) -> WidgetId {
WidgetId::from_hash(&self.text)
}
}§Cache Eviction
The cache uses LFU (Least Frequently Used) eviction when at capacity. Access count tracks usage; least-accessed entries are evicted first.
Structs§
- Cache
Stats - Statistics about cache performance.
- Measure
Cache - Thread-local cache for widget measure results.
- Widget
Id - Unique identifier for a widget instance.