microcad_lang/render/
cache.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Render cache.
5
6use std::{
7    hash::{Hash, Hasher},
8    rc::Rc,
9};
10
11use microcad_core::{Geometry2D, Geometry3D};
12
13/// Render hash type.
14#[derive(PartialEq, Eq, Default)]
15pub struct RenderHash(u64);
16
17impl Hash for RenderHash {
18    fn hash<H: Hasher>(&self, state: &mut H) {
19        state.write_u64(self.0);
20    }
21}
22
23/*pub trait RenderHashable: fmt::Display {
24    fn hash(&self) -> RenderHash {
25        let mut hasher = DefaultHasher::new();
26        self.to_string().hash(&mut hasher);
27        RenderHash(hasher.finish())
28    }
29}
30
31pub struct RenderHashed<T: RenderHashable> {
32    inner: T,
33    hash: RenderHash,
34}
35
36impl<T: RenderHashable> RenderHashed<T> {
37    pub fn new(inner: T) -> Self {
38        let hash = inner.hash();
39        Self { inner, hash }
40    }
41}*/
42
43/// An item in the [`RenderCache`].
44pub enum RenderCacheItem {
45    /// 2D geometry. Note: The Rc can be removed eventually, once the implementation of RenderHash is finished.
46    Geometry2D(Rc<Geometry2D>),
47    /// 3D geometry. Note: The Rc can be removed eventually, once the implementation of RenderHash is finished.
48    Geometry3D(Rc<Geometry3D>),
49}
50
51/// The [`RenderCache`] owns all geometry created during the render process.
52pub struct RenderCache(std::collections::HashMap<RenderHash, RenderCacheItem>);
53
54impl RenderCache {
55    /// Create a new empty cache.
56    pub fn new() -> Self {
57        Self(Default::default())
58    }
59
60    /// Empty cache.
61    pub fn clear(&mut self) {
62        self.0.clear();
63    }
64
65    /// Get 2D geometry from the cache.
66    pub fn get_2d(&self, hash: &RenderHash) -> Option<&Rc<Geometry2D>> {
67        match self.0.get(hash) {
68            Some(RenderCacheItem::Geometry2D(g)) => Some(g),
69            _ => None,
70        }
71    }
72
73    /// Get 3D geometry from the cache.
74    pub fn get_3d(&self, hash: &RenderHash) -> Option<&Rc<Geometry3D>> {
75        match self.0.get(hash) {
76            Some(RenderCacheItem::Geometry3D(g)) => Some(g),
77            _ => None,
78        }
79    }
80
81    /// Insert 2D geometry into the cache and return inserted geometry.
82    pub fn insert_2d(&mut self, hash: RenderHash, geo2d: Geometry2D) -> Rc<Geometry2D> {
83        let geo2d = Rc::new(geo2d);
84        self.0
85            .insert(hash, RenderCacheItem::Geometry2D(geo2d.clone()));
86        geo2d
87    }
88
89    /// Insert 3D geometry into the cache and return inserted geometry.
90    pub fn insert_3d(&mut self, hash: RenderHash, geo3d: Geometry3D) -> Rc<Geometry3D> {
91        let geo3d = Rc::new(geo3d);
92        self.0
93            .insert(hash, RenderCacheItem::Geometry3D(geo3d.clone()));
94        geo3d
95    }
96}
97
98impl Default for RenderCache {
99    fn default() -> Self {
100        Self::new()
101    }
102}