Skip to main content

mittens_engine/engine/ecs/component/
keyframe.rs

1use super::Component;
2use crate::engine::ecs::ComponentId;
3use crate::scripting::object::RuntimeClosure;
4
5#[derive(Debug, Clone)]
6pub struct KeyframeComponent {
7    /// When this keyframe should fire, in beats.
8    pub beat: f64,
9    pub callback: Option<RuntimeClosure>,
10
11    component: Option<ComponentId>,
12}
13
14impl KeyframeComponent {
15    pub fn new(beat: f64) -> Self {
16        Self {
17            beat,
18            callback: None,
19            component: None,
20        }
21    }
22
23    pub fn new_with_callback(beat: f64, callback: RuntimeClosure) -> Self {
24        Self {
25            beat,
26            callback: Some(callback),
27            component: None,
28        }
29    }
30
31    pub fn id(&self) -> Option<ComponentId> {
32        self.component
33    }
34}
35
36impl Component for KeyframeComponent {
37    fn set_id(&mut self, component: ComponentId) {
38        self.component = Some(component);
39    }
40
41    fn name(&self) -> &'static str {
42        "keyframe"
43    }
44
45    fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
46        emit.push_intent_now(
47            component,
48            crate::engine::ecs::IntentValue::RegisterKeyframe {
49                component_ids: vec![component],
50            },
51        );
52    }
53
54    fn as_any(&self) -> &dyn std::any::Any {
55        self
56    }
57
58    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
59        self
60    }
61
62    fn to_mms_ast(
63        &self,
64        _world: &crate::engine::ecs::World,
65    ) -> crate::scripting::ast::ComponentExpression {
66        use crate::engine::ecs::component::ce_helpers::*;
67        let mut ce = ce_call("Keyframe", "at", vec![num(self.beat)]);
68        if let Some(callback) = &self.callback {
69            ce.body = callback.body.clone();
70        }
71        ce
72    }
73}