pushrod/render/layout_cache.rs
1// Pushrod Rendering Library
2// Layout Caching Library
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use crate::render::layout::Layout;
17use crate::render::widget_cache::WidgetContainer;
18use std::cell::RefCell;
19
20/// This is a container object that stores a `Layout` object, and its ID.
21pub struct LayoutContainer {
22 pub layout: RefCell<Box<dyn Layout>>,
23 layout_id: i32,
24}
25
26/// This is an implementation that allows for creation of a `LayoutContainer`.
27impl LayoutContainer {
28 /// Creates a new `LayoutContainer`-wrapped `Layout` object.
29 pub fn new(layout: Box<dyn Layout>, layout_id: i32) -> Self {
30 Self {
31 layout: RefCell::new(layout),
32 layout_id,
33 }
34 }
35
36 /// Retrieves the current layout ID.
37 pub fn get_layout_id(&self) -> i32 {
38 self.layout_id
39 }
40}
41
42/// This is a container object that stores a `Vec` of `LayoutContainer` objects for its cache.
43pub struct LayoutCache {
44 cache: Vec<LayoutContainer>,
45}
46
47/// This is the implementation of the `LayoutCache`.
48impl LayoutCache {
49 pub fn new() -> Self {
50 Self { cache: Vec::new() }
51 }
52
53 /// Adds a `Box<Layout>` to the `Layout` stack.
54 pub fn add_layout(&mut self, layout: Box<dyn Layout>) -> i32 {
55 let layout_id = self.cache.len() as i32;
56
57 self.cache.push(LayoutContainer::new(layout, layout_id));
58
59 layout_id
60 }
61
62 /// Retrieves a `&mut LayoutContainer` object by its ID.
63 pub fn get_layout_by_id(&mut self, id: i32) -> &mut LayoutContainer {
64 &mut self.cache[id as usize]
65 }
66
67 /// Retrieves a borrowed slice of the `LayoutContainer` cache that can be sent to callbacks.
68 pub fn get_layout_cache(&self) -> &[LayoutContainer] {
69 &self.cache
70 }
71
72 /// Performs the `do_layout` call on `Layout` objects only if their `needs_layout` flag is set
73 /// to `true`.
74 pub fn do_layout(&self, widgets: &[WidgetContainer]) {
75 for x in &self.cache {
76 let needs_layout = x.layout.borrow().needs_layout();
77
78 if needs_layout {
79 x.layout.borrow_mut().do_layout(widgets);
80 }
81 }
82 }
83}
84
85impl Default for LayoutCache {
86 fn default() -> Self {
87 Self::new()
88 }
89}