mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-22 12:43:16 +00:00
better safe shared layout cache (#62)
This commit is contained in:
parent
0dc39434c2
commit
02573b0ad2
2 changed files with 17 additions and 12 deletions
|
@ -1,6 +1,7 @@
|
|||
use std::cell::RefCell;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use cassowary::strength::{MEDIUM, REQUIRED, WEAK};
|
||||
use cassowary::WeightedRelation::*;
|
||||
|
@ -68,8 +69,9 @@ pub struct Layout {
|
|||
expand_to_fill: bool,
|
||||
}
|
||||
|
||||
type Cache = HashMap<(Rect, Layout), Rc<[Rect]>>;
|
||||
thread_local! {
|
||||
static LAYOUT_CACHE: RefCell<HashMap<(Rect, Layout), Vec<Rect>>> = RefCell::new(HashMap::new());
|
||||
static LAYOUT_CACHE: RefCell<Cache> = RefCell::new(HashMap::new());
|
||||
}
|
||||
|
||||
impl Default for Layout {
|
||||
|
@ -139,8 +141,8 @@ impl Layout {
|
|||
/// height: 10,
|
||||
/// });
|
||||
/// assert_eq!(
|
||||
/// chunks,
|
||||
/// vec![
|
||||
/// chunks[..],
|
||||
/// [
|
||||
/// Rect {
|
||||
/// x: 2,
|
||||
/// y: 2,
|
||||
|
@ -166,8 +168,8 @@ impl Layout {
|
|||
/// height: 2,
|
||||
/// });
|
||||
/// assert_eq!(
|
||||
/// chunks,
|
||||
/// vec![
|
||||
/// chunks[..],
|
||||
/// [
|
||||
/// Rect {
|
||||
/// x: 0,
|
||||
/// y: 0,
|
||||
|
@ -183,7 +185,7 @@ impl Layout {
|
|||
/// ]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn split(&self, area: Rect) -> Vec<Rect> {
|
||||
pub fn split(&self, area: Rect) -> Rc<[Rect]> {
|
||||
// TODO: Maybe use a fixed size cache ?
|
||||
LAYOUT_CACHE.with(|c| {
|
||||
c.borrow_mut()
|
||||
|
@ -194,7 +196,7 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
fn split(area: Rect, layout: &Layout) -> Vec<Rect> {
|
||||
fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
|
||||
let mut solver = Solver::new();
|
||||
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
|
||||
let elements = layout
|
||||
|
@ -202,11 +204,13 @@ fn split(area: Rect, layout: &Layout) -> Vec<Rect> {
|
|||
.iter()
|
||||
.map(|_| Element::new())
|
||||
.collect::<Vec<Element>>();
|
||||
let mut results = layout
|
||||
let mut res = layout
|
||||
.constraints
|
||||
.iter()
|
||||
.map(|_| Rect::default())
|
||||
.collect::<Vec<Rect>>();
|
||||
.collect::<Rc<[Rect]>>();
|
||||
|
||||
let mut results = Rc::get_mut(&mut res).expect("newly created Rc should have no shared refs");
|
||||
|
||||
let dest_area = area.inner(&layout.margin);
|
||||
for (i, e) in elements.iter().enumerate() {
|
||||
|
@ -343,7 +347,7 @@ fn split(area: Rect, layout: &Layout) -> Vec<Rect> {
|
|||
}
|
||||
}
|
||||
}
|
||||
results
|
||||
res
|
||||
}
|
||||
|
||||
/// A container used by the solver inside split
|
||||
|
|
|
@ -280,7 +280,7 @@ impl<'a> Table<'a> {
|
|||
if !self.widths.is_empty() {
|
||||
constraints.pop();
|
||||
}
|
||||
let mut chunks = Layout::default()
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints(constraints)
|
||||
.expand_to_fill(false)
|
||||
|
@ -290,8 +290,9 @@ impl<'a> Table<'a> {
|
|||
width: max_width,
|
||||
height: 1,
|
||||
});
|
||||
let mut chunks = &chunks[..];
|
||||
if has_selection {
|
||||
chunks.remove(0);
|
||||
chunks = &chunks[1..];
|
||||
}
|
||||
chunks.iter().step_by(2).map(|c| c.width).collect()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue