1use std::collections::{HashSet,HashMap};
2use std::mem;
3use uuid::Uuid;
4
5use graphics::{ Graphics, ImageSize };
6use graphics::math::{ Matrix2d };
7
8use input::GenericEvent;
9use ai_behavior::{
10 Behavior,
11 State,
12 Running,
13};
14
15use sprite::Sprite;
16
17use animation::{
18 Animation,
19 AnimationState,
20};
21
22pub struct Scene<I: ImageSize> {
24 children: Vec<Sprite<I>>,
25 children_index: HashMap<Uuid, usize>,
26 running: HashMap<Uuid,
27 Vec<(Behavior<Animation>, State<Animation, AnimationState>, bool)>>,
28 dead_sprites: HashSet<Uuid>,
30}
31
32impl<I: ImageSize> Scene<I> {
33 pub fn new() -> Scene<I> {
35 Scene {
36 children: Vec::new(),
37 children_index: HashMap::new(),
38 running: HashMap::new(),
39 dead_sprites: HashSet::new(),
40 }
41 }
42
43 pub fn event<E>(&mut self, e: &E) where E: GenericEvent {
45 let running = mem::take(&mut self.running);
47
48 for (id, animations) in running.into_iter() {
49 let mut new_animations = Vec::new();
50
51 for (b, mut a, paused) in animations.into_iter() {
52 if paused {
53 new_animations.push((b, a, paused));
54 continue;
55 }
56
57 let sprite = self.child_mut(id).unwrap();
58 let (status, _) = a.event(e, &mut |args| {
59 let (state, status, remain) = {
60 let start_state;
61 let state = match *args.state {
62 None => { start_state = args.action.to_state(sprite); &start_state },
63 Some(ref state) => state,
64 };
65 state.update(sprite, args.dt)
66 };
67 *args.state = state;
68 (status, remain)
69 });
70
71 match status {
72 Running => {
74 new_animations.push((b, a, paused));
75 },
76 _ => {},
77 }
78 }
79
80 if !new_animations.is_empty() {
81 self.running.insert(id, new_animations);
82 }
83 }
84
85 self.prune_dead_sprites();
86 }
87
88 fn prune_dead_sprites(&mut self) {
89 if !self.dead_sprites.is_empty() {
90 let mut to_remove = HashSet::new();
91
92 for sprite_id in self.dead_sprites.iter() {
93 let n = self.running_for_child(*sprite_id)
94 .expect("Assert failed: invalid internal state for dead_sprites");
95
96 if n == 0 {
97 to_remove.insert(*sprite_id);
98 }
99 }
100
101 for sprite_id in to_remove.iter() {
102 self.remove_child(*sprite_id);
103 }
104 }
105 }
106
107 pub fn draw<B: Graphics<Texture = I>>(&self, t: Matrix2d, b: &mut B) {
109 for child in &self.children {
110 child.draw(t, b);
111 }
112 }
113
114 pub fn draw_tinted<B: Graphics<Texture = I>>(&self, t: Matrix2d, b: &mut B, c: [f32;3]) {
116 for child in &self.children {
117 child.draw_tinted(t,b,c)
118 }
119 }
120
121 pub fn run(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
123 use std::collections::hash_map::Entry::{ Vacant, Occupied };
124 let animations = match self.running.entry(sprite_id) {
125 Vacant(entry) => entry.insert(Vec::new()),
126 Occupied(entry) => entry.into_mut()
127 };
128 let state = State::new(animation.clone());
129 animations.push((animation.clone(), state, false));
130 }
131
132 fn find(&self, sprite_id: Uuid, animation: &Behavior<Animation>) -> Option<usize> {
133 let mut index = None;
134 if let Some(animations) = self.running.get(&sprite_id) {
135 for (i, &(ref b, _, _)) in animations.iter().enumerate() {
136 if b == animation {
137 index = Some(i);
138 break;
139 }
140 }
141 }
142 index
143 }
144
145 pub fn pause(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
147 if let Some(index) = self.find(sprite_id, animation) {
148 let animations = self.running.get_mut(&sprite_id).unwrap();
149 let (b, s, _) = animations.remove(index);
150 animations.push((b, s, true));
151 }
152 }
153
154 pub fn resume(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
156 if let Some(index) = self.find(sprite_id, animation) {
157 let animations = self.running.get_mut(&sprite_id).unwrap();
158 let (b, s, _) = animations.remove(index);
159 animations.push((b, s, false));
160 }
161 }
162
163 pub fn toggle(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
165 if let Some(index) = self.find(sprite_id, animation) {
166 let animations = self.running.get_mut(&sprite_id).unwrap();
167 let (b, s, paused) = animations.remove(index);
168 animations.push((b, s, !paused));
169 }
170 }
171
172 pub fn stop(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
174 if let Some(index) = self.find(sprite_id, animation) {
175 self.running.get_mut(&sprite_id).unwrap().remove(index);
176 }
177 }
178
179 pub fn stop_all(&mut self, sprite_id: Uuid) {
181 self.running.remove(&sprite_id);
182 }
183
184 pub fn running(&self) -> usize {
186 let mut total = 0;
187 for (_, animations) in &self.running {
188 total += animations.len();
189 }
190 total
191 }
192
193 pub fn running_for_child(&self, sprite_id: Uuid) -> Option<usize> {
196 if let Some(animations) = self.running.get(&sprite_id) {
197 Some(animations.len())
198 } else {
199 if self.child(sprite_id).is_some() {
200 Some(0)
201 } else {
202 None
203 }
204 }
205 }
206
207 pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
209 let id = sprite.id();
210 self.children.push(sprite);
211 self.children_index.insert(id.clone(), self.children.len() - 1);
212 id
213 }
214
215 fn stop_all_including_children(&mut self, sprite: &Sprite<I>) {
216 self.stop_all(sprite.id());
217 for child in sprite.children().iter() {
218 self.stop_all_including_children(child);
219 }
220 }
221
222 pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
225 let removed = if let Some(index) = self.children_index.remove(&id) {
226 let removed = self.children.remove(index);
227 for i in index..self.children.len() {
230 let uuid = self.children[i].id();
231 self.children_index.insert(uuid, i);
232 }
233 Some(removed)
234 } else {
235 for child in &mut self.children {
236 if let Some(c) = child.remove_child(id.clone()) {
237 return Some(c);
238 }
239 }
240 None
241 };
242
243 if removed.is_some() {
244 self.dead_sprites.remove(&id);
245 self.stop_all_including_children(removed.as_ref().unwrap());
246 }
247
248 removed
249 }
250
251 pub fn remove_child_when_done(&mut self, id: Uuid) {
256 match self.running_for_child(id) {
257 Some(n) => {
258 if n == 0 {
259 self.remove_child(id);
260 } else {
261 self.dead_sprites.insert(id);
262 }
263 },
264 None => {}
265 }
266 }
267
268 pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
270 if let Some(index) = self.children_index.get(&id) {
271 Some(&self.children[*index])
272 } else {
273 for child in &self.children {
274 if let Some(c) = child.child(id.clone()) {
275 return Some(c);
276 }
277 }
278 None
279 }
280 }
281
282 pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
284 if let Some(index) = self.children_index.get(&id) {
285 Some(&mut self.children[*index])
286 } else {
287 for child in &mut self.children {
288 if let Some(c) = child.child_mut(id.clone()) {
289 return Some(c);
290 }
291 }
292 None
293 }
294 }
295
296 #[inline(always)]
298 pub fn children(&self) -> &Vec<Sprite<I>> {
299 &self.children
300 }
301}