ascending_graphics/systems/
layout.rs1use crate::{AHashMap, GpuDevice};
2use bytemuck::{Pod, Zeroable};
3use std::{
4 any::{Any, TypeId},
5 sync::Arc,
6};
7
8pub trait Layout: Pod + Zeroable {
11 fn create_layout(
14 &self,
15 gpu_device: &mut GpuDevice,
16 ) -> wgpu::BindGroupLayout;
17
18 fn layout_key(&self) -> (TypeId, Vec<u8>) {
21 let type_id = self.type_id();
22 let bytes: Vec<u8> =
23 bytemuck::try_cast_slice(&[*self]).unwrap_or(&[]).to_vec();
24
25 (type_id, bytes)
26 }
27}
28
29#[derive(Debug)]
32pub struct LayoutStorage {
33 pub(crate) bind_group_map:
34 AHashMap<(TypeId, Vec<u8>), Arc<wgpu::BindGroupLayout>>,
35}
36
37impl LayoutStorage {
38 pub fn new() -> Self {
41 Self {
42 bind_group_map: AHashMap::default(),
43 }
44 }
45
46 pub fn create_layout<K: Layout>(
49 &mut self,
50 device: &mut GpuDevice,
51 layout: K,
52 ) -> Arc<wgpu::BindGroupLayout> {
53 let key = layout.layout_key();
54
55 let layout = self
56 .bind_group_map
57 .entry(key)
58 .or_insert_with(|| Arc::new(layout.create_layout(device)));
59
60 Arc::clone(layout)
61 }
62
63 pub fn get_layout<K: Layout>(
64 &self,
65 layout: K,
66 ) -> Option<Arc<wgpu::BindGroupLayout>> {
67 let key = layout.layout_key();
68
69 self.bind_group_map.get(&key).map(Arc::clone)
70 }
71}
72
73impl Default for LayoutStorage {
74 fn default() -> Self {
75 Self::new()
76 }
77}