wutengine/plugins/
mod.rs

1//! Module for implementable engine plugins
2
3use core::any::Any;
4use core::fmt::Debug;
5use std::collections::HashMap;
6
7use crate::context::{
8    EngineContext, GraphicsContext, MessageContext, ViewportContext, WindowContext,
9};
10use crate::runtime::messaging::MessageQueue;
11use crate::windowing::window::WindowData;
12use crate::winit::event::{DeviceEvent, DeviceId, WindowEvent};
13use wutengine_core::identifiers::WindowIdentifier;
14
15use crate::runtime::RuntimeInitializer;
16
17/// Trait for WutEngine plugins.
18/// These plugins are meant to be lower-level extensions to the engine runtime,
19/// allowing for responses to raw events as well as injection
20/// of custom systems and commands at key points in the engine lifecycle
21pub trait WutEnginePlugin: Any + Send + Sync + Debug {
22    /// Casts the plugin to an instance of [Any], for possible downcasting later
23    fn as_any(&self) -> &dyn Any;
24
25    /// Called once right after [RuntimeInitializer::run] is called
26    fn on_build(&mut self, _initializer: &mut RuntimeInitializer) {}
27
28    /// Called once when the runtime has just been built, and is starting
29    fn on_start(&mut self, _context: &mut Context) {}
30
31    /// The physics update hook. Any interaction with the physics
32    /// components should happen here
33    fn physics_update(&mut self, _context: &mut Context) {}
34
35    /// Post-physics update hook. Used for any interactions
36    /// following updates to physics components.
37    fn post_physics_update(&mut self, _context: &mut Context) {}
38
39    /// Hook exclusive to WutEngine plugins, ran after all physics and post-physics
40    /// updates. At this point, all physics components have been synchronized, and can
41    /// no longer be accessed by user scripts unless a message is sent to them.
42    ///
43    /// This basically allows the plugin to step any internal physics solvers,
44    /// with the knowledge that all physics data that was going to be updated has
45    /// actually been updated.
46    fn physics_solver_update(&mut self, _context: &mut Context) {}
47
48    /// Called before starting each update tick
49    fn pre_update(&mut self, _context: &mut Context) {}
50
51    /// Called on each update tick
52    fn update(&mut self, _context: &mut Context) {}
53
54    /// Called once for each raw window event returned by the windowing system (currently [winit])
55    fn on_window_event(
56        &mut self,
57        _window: &WindowIdentifier,
58        _event: &WindowEvent,
59        _context: &mut Context,
60    ) {
61    }
62
63    /// Called once for each raw device event returned by the windowing system (currently [winit])
64    fn on_device_event(&mut self, _device: DeviceId, _event: &DeviceEvent, _context: &mut Context) {
65    }
66}
67
68/// The context handed to most plugin hooks. Can be used to access the engine APIs
69pub struct Context<'a> {
70    /// The engine context
71    pub engine: EngineContext<'a>,
72
73    /// The message context
74    pub message: MessageContext<'a>,
75
76    /// The viewport context
77    pub viewport: ViewportContext<'a>,
78
79    /// The graphics context
80    pub graphics: GraphicsContext<'a>,
81
82    /// The windowing context
83    pub windows: WindowContext<'a>,
84}
85
86impl<'a> Context<'a> {
87    /// Creates a new plugin context with the given parameters
88    pub(crate) fn new(
89        windows: &'a HashMap<WindowIdentifier, WindowData>,
90        messages: &'a MessageQueue,
91    ) -> Self {
92        Self {
93            engine: EngineContext::new(),
94            message: MessageContext::new(messages),
95            viewport: ViewportContext::new(),
96            graphics: GraphicsContext::new(),
97            windows: WindowContext::new(windows),
98        }
99    }
100}