mirror of
https://github.com/ratatui-org/ratatui
synced 2025-02-16 22:18:51 +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::cell::RefCell;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use cassowary::strength::{MEDIUM, REQUIRED, WEAK};
|
use cassowary::strength::{MEDIUM, REQUIRED, WEAK};
|
||||||
use cassowary::WeightedRelation::*;
|
use cassowary::WeightedRelation::*;
|
||||||
|
@ -68,8 +69,9 @@ pub struct Layout {
|
||||||
expand_to_fill: bool,
|
expand_to_fill: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Cache = HashMap<(Rect, Layout), Rc<[Rect]>>;
|
||||||
thread_local! {
|
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 {
|
impl Default for Layout {
|
||||||
|
@ -139,8 +141,8 @@ impl Layout {
|
||||||
/// height: 10,
|
/// height: 10,
|
||||||
/// });
|
/// });
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// chunks,
|
/// chunks[..],
|
||||||
/// vec![
|
/// [
|
||||||
/// Rect {
|
/// Rect {
|
||||||
/// x: 2,
|
/// x: 2,
|
||||||
/// y: 2,
|
/// y: 2,
|
||||||
|
@ -166,8 +168,8 @@ impl Layout {
|
||||||
/// height: 2,
|
/// height: 2,
|
||||||
/// });
|
/// });
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// chunks,
|
/// chunks[..],
|
||||||
/// vec![
|
/// [
|
||||||
/// Rect {
|
/// Rect {
|
||||||
/// x: 0,
|
/// x: 0,
|
||||||
/// y: 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 ?
|
// TODO: Maybe use a fixed size cache ?
|
||||||
LAYOUT_CACHE.with(|c| {
|
LAYOUT_CACHE.with(|c| {
|
||||||
c.borrow_mut()
|
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 solver = Solver::new();
|
||||||
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
|
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
|
||||||
let elements = layout
|
let elements = layout
|
||||||
|
@ -202,11 +204,13 @@ fn split(area: Rect, layout: &Layout) -> Vec<Rect> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|_| Element::new())
|
.map(|_| Element::new())
|
||||||
.collect::<Vec<Element>>();
|
.collect::<Vec<Element>>();
|
||||||
let mut results = layout
|
let mut res = layout
|
||||||
.constraints
|
.constraints
|
||||||
.iter()
|
.iter()
|
||||||
.map(|_| Rect::default())
|
.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);
|
let dest_area = area.inner(&layout.margin);
|
||||||
for (i, e) in elements.iter().enumerate() {
|
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
|
/// A container used by the solver inside split
|
||||||
|
|
|
@ -280,7 +280,7 @@ impl<'a> Table<'a> {
|
||||||
if !self.widths.is_empty() {
|
if !self.widths.is_empty() {
|
||||||
constraints.pop();
|
constraints.pop();
|
||||||
}
|
}
|
||||||
let mut chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints(constraints)
|
.constraints(constraints)
|
||||||
.expand_to_fill(false)
|
.expand_to_fill(false)
|
||||||
|
@ -290,8 +290,9 @@ impl<'a> Table<'a> {
|
||||||
width: max_width,
|
width: max_width,
|
||||||
height: 1,
|
height: 1,
|
||||||
});
|
});
|
||||||
|
let mut chunks = &chunks[..];
|
||||||
if has_selection {
|
if has_selection {
|
||||||
chunks.remove(0);
|
chunks = &chunks[1..];
|
||||||
}
|
}
|
||||||
chunks.iter().step_by(2).map(|c| c.width).collect()
|
chunks.iter().step_by(2).map(|c| c.width).collect()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue