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}