wutengine/component/mod.rs
1//! Component related functionality and data
2
3use core::any::Any;
4use core::fmt::Debug;
5use core::marker::PhantomData;
6
7use crate::context::{
8 EngineContext, GameObjectContext, GraphicsContext, MessageContext, ViewportContext,
9};
10use crate::context::{PluginContext, WindowContext};
11use crate::runtime::messaging::Message;
12
13pub(crate) mod data;
14
15/// A component, the core programmable unit in WutEngine.
16pub trait Component: Any + Send + Sync + Debug {
17 /// Called before the first update cycle this component is active in
18 fn on_start(&mut self, _context: &mut Context) {}
19
20 /// Called right before this component is destroyed.
21 fn on_destroy(&mut self, _context: &mut Context) {}
22
23 /// The physics update hook. Any interaction with the physics
24 /// components should happen here
25 fn physics_update(&mut self, _context: &mut Context) {}
26
27 /// Post-physics update hook. Used for any interactions
28 /// following updates to physics components.
29 fn post_physics_update(&mut self, _context: &mut Context) {}
30
31 /// The pre-update hook. Runs before all the update hooks
32 fn pre_update(&mut self, _context: &mut Context) {}
33
34 /// The main update hook. Runs each frame. Use this in most cases
35 fn update(&mut self, _context: &mut Context) {}
36
37 /// The pre-render hook. Runs after the update phase. Use this for submitting
38 /// rendering commands
39 fn pre_render(&mut self, _context: &mut Context) {}
40
41 /// Called for each message that might be relevant for this component.
42 fn on_message(&mut self, _context: &mut Context, _message: &Message) {}
43
44 /// Converts the component reference to a dyn [Any] reference.
45 fn as_any(&self) -> &dyn Any;
46
47 /// Converts the component mutable reference to a dyn [Any] mutable reference.
48 fn as_any_mut(&mut self) -> &mut dyn Any;
49}
50
51/// The main context handed to each component each frame
52pub struct Context<'a> {
53 /// Engine related APIs and commands
54 pub engine: &'a EngineContext<'a>,
55
56 /// Information and APIs related to the gameobject this component is on
57 pub gameobject: GameObjectContext<'a>,
58
59 /// The message context
60 pub message: &'a MessageContext<'a>,
61
62 /// The loaded plugins
63 pub plugin: &'a PluginContext<'a>,
64
65 /// Information and APIs for interacting with viewports
66 pub viewport: &'a ViewportContext<'a>,
67
68 /// Graphics and rendering APIs
69 pub graphics: &'a GraphicsContext<'a>,
70
71 /// Window information and APIs
72 pub window: &'a WindowContext<'a>,
73
74 /// Engine APIs and functions for the current component
75 pub this: ComponentContext<'a>,
76}
77
78/// Context for interacting with APIs and functions related to the
79/// current component.
80#[derive(Debug)]
81pub struct ComponentContext<'a> {
82 /// Whether the component should be marked as dying ASAP.
83 pub(crate) should_die: bool,
84
85 ph: PhantomData<&'a ()>,
86}
87
88impl ComponentContext<'_> {
89 /// Creates a new, empty context
90 pub(crate) fn new() -> Self {
91 Self {
92 should_die: false,
93 ph: PhantomData,
94 }
95 }
96 /// Marks the component this context is for as dying, preventing further new component
97 /// hooks to be called on it and allowing it to be cleaned up by the engine runtime.
98 pub fn destroy(&mut self) {
99 self.should_die = true;
100 }
101}