1use crate::gfx::Gfx;
2use std::{
3 any::{Any, TypeId},
4 collections::HashMap,
5};
6pub type HashTypeId2Data = HashMap<TypeId, Box<dyn Any>>;
7pub trait Ready {
13 fn ready(&mut self, data: &mut HashTypeId2Data, gfx: &Gfx);
14}
15pub trait Paint {
19 fn paint(data: &mut HashTypeId2Data, gfx: &Gfx);
20}
21pub trait Update {
27 fn update(data: &mut HashTypeId2Data, gfx: &Gfx);
28}
29pub trait Pass<'a> {
35 fn pass(
36 data: &mut HashTypeId2Data,
37 render_pass: &'a mut wgpu::RenderPass<'a>,
38 ) -> &'a mut wgpu::RenderPass<'a>;
39}
40
41pub trait Queue {
45 fn introduce(scene: &mut Scene);
46}
47
48pub fn get_res<T: Any + 'static>(data: &HashTypeId2Data) -> &T {
50 data.get(&TypeId::of::<T>())
51 .and_then(|data| data.downcast_ref::<T>())
52 .expect(&format!(
53 "Failed to get resource of type: {}",
54 std::any::type_name::<T>()
55 ))
56}
57pub fn get_res_mut<T: Any + 'static>(data: &mut HashTypeId2Data) -> &mut T {
59 data.get_mut(&TypeId::of::<T>())
60 .and_then(|data| data.downcast_mut::<T>())
61 .expect(&format!(
62 "Failed to get mutable resource of type: {}",
63 std::any::type_name::<T>()
64 ))
65}
66
67pub fn get_ref_and_mut<Ref: Any + 'static, Mut: Any + 'static>(
69 data: &mut HashTypeId2Data,
70) -> (&Ref, &mut Mut) {
71 assert_ne!(
72 TypeId::of::<Ref>(),
73 TypeId::of::<Mut>(),
74 "Ref and Mut should not be the same type"
75 );
76 unsafe {
77 let data_ptr = data as *mut HashTypeId2Data;
78 let t1 = (&*data_ptr)
79 .get(&TypeId::of::<Ref>())
80 .and_then(|r| r.downcast_ref::<Ref>())
81 .expect(&format!(
82 "Failed to get resource of type: {}",
83 std::any::type_name::<Ref>()
84 ));
85 let t2 = (&mut *data_ptr)
86 .get_mut(&TypeId::of::<Mut>())
87 .and_then(|d| d.downcast_mut::<Mut>())
88 .expect(&format!(
89 "Failed to get mutable resource of type: {}",
90 std::any::type_name::<Mut>()
91 ));
92 (t1, t2)
93 }
94}
95
96pub fn return_res<T: Any + 'static>(data: &mut HashMap<TypeId, Box<dyn Any>>, new_data: T) {
98 data.insert(TypeId::of::<T>(), Box::new(new_data));
99}
100
101pub struct Scene {
102 readys: Vec<TypeId>,
103 paints: Vec<TypeId>,
104 readys_hashmap: HashMap<TypeId, Box<dyn FnMut(&mut HashMap<TypeId, Box<dyn Any>>, &Gfx)>>,
105 paints_hashmap: HashMap<TypeId, Box<dyn FnMut(&mut HashMap<TypeId, Box<dyn Any>>, &Gfx)>>,
106 res: HashMap<TypeId, Box<dyn Any>>,
107 name: String,
108}
109impl Scene {
110 pub fn get_name(&self) -> &str {
111 &self.name
112 }
113 pub fn new(name: impl Into<String>) -> Self {
114 Scene {
115 res: HashMap::new(),
116 paints_hashmap: HashMap::new(),
117 readys: Vec::new(),
118 name: name.into(),
119 paints: Vec::new(),
120 readys_hashmap: HashMap::new(),
121 }
122 }
123
124 pub fn add_ready<T: Ready + Default + 'static>(&mut self, mut ready_res: T) -> &mut Self {
125 let type_id = TypeId::of::<T>();
126 self.readys.push(type_id);
127 self.res.insert(type_id, Box::new(T::default()));
128 self.readys_hashmap.insert(
129 type_id,
130 Box::new(move |data, gfx| {
131 ready_res.ready(data, gfx);
132 }),
133 );
134
135 self
136 }
137
138 pub fn add_paint<T: Paint + 'static>(&mut self) {
139 let type_id = TypeId::of::<T>();
140 self.paints.push(type_id);
141 self.paints_hashmap.insert(type_id, Box::new(T::paint));
142 }
143
144 pub fn ready(&mut self, gfx: &Gfx) {
145 println!("<Scene>::ready");
146 for ready_type_id in self.readys.iter() {
147 if let Some(ready_fn) = self.readys_hashmap.get_mut(ready_type_id) {
148 ready_fn(&mut self.res, gfx);
149 }
150 }
151 }
152
153 pub fn paint(&mut self, gfx: &Gfx) {
154 for paint_type_id in self.paints.iter() {
155 if let Some(paint_fn) = self.paints_hashmap.get_mut(paint_type_id) {
156 paint_fn(&mut self.res, gfx);
157 }
158 }
159 }
160}