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