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}