mraphics_core/
mesh_pool.rs1use crate::{MeshHandle, MeshLike, MraphicsID, RenderInstance};
2use std::{any::TypeId, collections::HashMap, mem, ptr};
3
4pub struct MeshBox {
8 data: *mut u8,
9
10 type_id: TypeId,
11
12 size: usize,
13 align: usize,
14 drop_fn: unsafe fn(*mut u8),
15
16 update_fn: unsafe fn(*mut u8),
17 update_instance_fn: unsafe fn(*mut u8, instance: &mut RenderInstance),
18}
19
20impl MeshBox {
21 pub fn new<M: MeshLike + 'static>(mesh: M) -> Self {
22 let layout = std::alloc::Layout::new::<M>();
23 let ptr = unsafe { std::alloc::alloc(layout) };
24
25 unsafe {
26 ptr::write(ptr as *mut M, mesh);
27 }
28
29 Self {
30 data: ptr,
31
32 type_id: TypeId::of::<M>(),
33
34 size: mem::size_of::<M>(),
35 align: mem::align_of::<M>(),
36 drop_fn: |ptr| unsafe {
37 let layout = std::alloc::Layout::new::<M>();
38 ptr::drop_in_place(ptr as *mut M);
39 std::alloc::dealloc(ptr, layout);
40 },
41
42 update_fn: |ptr| unsafe {
43 (&mut *(ptr as *mut M)).update();
44 },
45 update_instance_fn: |ptr, instance| unsafe {
46 (&mut *(ptr as *mut M)).update_instance(instance);
47 },
48 }
49 }
50
51 pub fn size(&self) -> usize {
53 self.size
54 }
55
56 pub fn align(&self) -> usize {
58 self.align
59 }
60
61 pub fn is<M: MeshLike + 'static>(&self) -> bool {
63 self.type_id == TypeId::of::<M>()
64 }
65
66 pub fn downcast_ref<M: MeshLike + 'static>(&self) -> Option<&M> {
69 if self.is::<M>() {
70 Some(self.downcast_ref_unchecked::<M>())
71 } else {
72 None
73 }
74 }
75
76 pub fn downcast_ref_unchecked<M: MeshLike + 'static>(&self) -> &M {
82 unsafe { &*(self.data as *const M) }
83 }
84
85 pub fn downcast_mut<M: MeshLike + 'static>(&mut self) -> Option<&mut M> {
88 if self.is::<M>() {
89 Some(self.downcast_mut_unchecked::<M>())
90 } else {
91 None
92 }
93 }
94
95 pub fn downcast_mut_unchecked<M: MeshLike + 'static>(&mut self) -> &mut M {
101 unsafe { &mut *(self.data as *mut M) }
102 }
103
104 pub fn update_mesh(&mut self) {
106 unsafe { (self.update_fn)(self.data) }
109 }
110
111 pub fn update_instance(&mut self, instance: &mut RenderInstance) {
113 unsafe { (self.update_instance_fn)(self.data, instance) }
116 }
117}
118
119impl Drop for MeshBox {
120 fn drop(&mut self) {
121 unsafe { (self.drop_fn)(self.data) }
122 }
123}
124
125pub struct MeshPool {
126 pub meshes: Vec<MeshBox>,
127 mesh_map: HashMap<MraphicsID, usize>,
128}
129
130impl MeshPool {
131 pub fn new() -> Self {
132 Self {
133 meshes: Vec::new(),
134 mesh_map: HashMap::new(),
135 }
136 }
137
138 pub fn add_mesh<M: MeshLike + 'static>(&mut self, mesh: M) -> MeshHandle<M> {
139 let id = mesh.identifier();
140
141 self.meshes.push(MeshBox::new(mesh));
142 self.mesh_map.insert(id, self.meshes.len() - 1);
143
144 MeshHandle::<M>::new(id)
145 }
146
147 pub fn update_mesh(&mut self, id: MraphicsID) {
149 self.meshes[*self.mesh_map.get(&id).unwrap()].update_mesh();
150 }
151
152 pub fn update_instance(&mut self, id: MraphicsID, instance: &mut RenderInstance) {
154 self.meshes[*self.mesh_map.get(&id).unwrap()].update_instance(instance);
155 }
156
157 pub fn acquire_mesh<M: MeshLike + 'static>(&self, id: MraphicsID) -> Option<&M> {
158 self.meshes[*self.mesh_map.get(&id).unwrap()].downcast_ref::<M>()
159 }
160
161 pub fn acquire_mesh_unchecked<M: MeshLike + 'static>(&self, id: MraphicsID) -> &M {
162 self.meshes[*self.mesh_map.get(&id).unwrap()]
163 .downcast_ref::<M>()
164 .unwrap()
165 }
166
167 pub fn acquire_mesh_mut<M: MeshLike + 'static>(&mut self, id: MraphicsID) -> Option<&mut M> {
168 self.meshes[*self.mesh_map.get(&id).unwrap()].downcast_mut::<M>()
169 }
170
171 pub fn acquire_mesh_mut_unchecked<M: MeshLike + 'static>(&mut self, id: MraphicsID) -> &mut M {
172 self.meshes[*self.mesh_map.get(&id).unwrap()]
173 .downcast_mut::<M>()
174 .unwrap()
175 }
176}