1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use super::*; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SceneItem { start: f64, z: i64, animated: Box<dyn Animated>, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Scene { items: Vec<SceneItem>, duration: f64, size: Size, } impl Scene { pub fn new() -> Self { Scene { items: Vec::new(), duration: 0f64, size: Size::default(), } } pub fn add(&mut self, animated: Box<dyn Animated>, start: f64, z: i64) { let size = animated.size(); let end = start + animated.duration(); self.items.push(SceneItem { animated, start, z }); self.size.x = self.size.x.max(size.x); self.size.y = self.size.y.max(size.y); self.duration = self.duration.max(end); } pub fn register(engine: &mut rhai::Engine) { use rhai::RegisterFn; engine.register_type::<Scene>(); engine.register_fn("scene", Scene::new); engine.register_fn("add", Scene::add); engine.register_fn("as_animated", Scene::as_animated); } } #[typetag::serde(name = "scene")] impl Animated for Scene { fn draw(&self, context: &cairo::Context, offset: f64) { let mut items: Vec<&SceneItem> = self.items .iter() .filter(|i| i.start <= offset && (i.start + i.animated.duration()) > offset) .collect(); items.sort_by_key(|i| i.z); for item in items { item.animated.draw(context, offset - item.start); } } fn size(&self) -> Size { self.size } fn duration(&self) -> f64 { self.duration } fn audio(&self) -> Box<dyn Iterator<Item = AudioItem>> { let audios: Vec<Box<dyn Iterator<Item = AudioItem>>> = self.items.iter().map(|i| i.animated.audio()).collect(); Box::new(audios.into_iter().flatten()) } }