1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use crate::Vec2;
use crate::XY;
/// Cache around a one-dimensional layout result.
///
/// This is not a View, but something to help you if you create your own Views.
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
pub struct SizeCache<T = ()> {
/// Cached value
pub value: usize,
/// `true` if the last size was constrained.
///
/// If unconstrained, any request larger than this value
/// would return the same size.
pub constrained: bool,
/// Extra field.
pub extra: T,
}
impl SizeCache<()> {
/// Creates a new sized cache
pub fn new(value: usize, constrained: bool) -> Self {
SizeCache {
value,
constrained,
extra: (),
}
}
/// Creates a new bi-dimensional cache.
///
/// It will stay valid for the same request, and compatible ones.
///
/// A compatible request is one where, for each axis, either:
///
/// * the request is equal to the cached size, or
/// * the request is larger than the cached size and the cache is
/// unconstrained
///
/// Notes:
///
/// * `size` must fit inside `req`.
/// * for each dimension, `constrained = (size == req)`
pub fn build(size: Vec2, req: Vec2) -> XY<Self> {
size.zip_map(req, |size, req| SizeCache::new(size, size >= req))
}
}
impl<T> SizeCache<T> {
/// Creates a new sized cache
pub fn new_extra(value: usize, constrained: bool, extra: T) -> Self {
Self {
value,
constrained,
extra,
}
}
/// Creates a new bi-dimensional cache.
///
/// Similar to `build()`, but includes the extra field.
pub fn build_extra(size: Vec2, req: Vec2, extra: XY<T>) -> XY<Self> {
XY::zip3(size, req, extra).map(|(size, req, extra)| {
SizeCache::new_extra(size, size >= req, extra)
})
}
/// Returns `true` if `self` is still valid for the given `request`.
pub fn accept(self, request: usize) -> bool {
match (request, self.value) {
// Request a smaller size than last time? Hell no!
(r, v) if r < v => false,
// Request exactly what we had last time? Sure!
(r, v) if r == v => true,
// Request more than we had last time? Maybe?
_ => !self.constrained,
}
}
/// Returns the value in the cache.
pub fn value(self) -> usize {
self.value
}
}