Skip to main content

freya_winit/
plugins.rs

1use std::{
2    cell::RefCell,
3    collections::HashMap,
4    rc::Rc,
5};
6
7use freya_core::integration::*;
8use freya_engine::prelude::{
9    Canvas,
10    FontCollection,
11};
12pub use keyboard_types::{
13    Code,
14    Key,
15    Modifiers,
16};
17use winit::{
18    event_loop::EventLoopProxy,
19    window::{
20        Window,
21        WindowId,
22    },
23};
24
25use crate::renderer::{
26    NativeEvent,
27    NativeWindowEvent,
28    NativeWindowEventAction,
29};
30
31#[derive(Clone)]
32pub struct PluginHandle {
33    pub proxy: EventLoopProxy<NativeEvent>,
34}
35
36impl PluginHandle {
37    pub fn new(proxy: &EventLoopProxy<NativeEvent>) -> Self {
38        Self {
39            proxy: proxy.clone(),
40        }
41    }
42
43    /// Emit a [PlatformEvent]. Useful to simulate certain events.
44    pub fn send_platform_event(&self, event: PlatformEvent, window_id: WindowId) {
45        self.proxy
46            .send_event(NativeEvent::Window(NativeWindowEvent {
47                window_id,
48                action: NativeWindowEventAction::PlatformEvent(event),
49            }))
50            .ok();
51    }
52
53    /// Emit a [NativeEvent].
54    pub fn send_event_loop_event(&self, event: NativeEvent) {
55        self.proxy.send_event(event).ok();
56    }
57}
58
59/// Manages all loaded plugins.
60#[derive(Default, Clone)]
61pub struct PluginsManager {
62    plugins: Rc<RefCell<HashMap<&'static str, Box<dyn FreyaPlugin>>>>,
63}
64
65impl PluginsManager {
66    /// Add a plugin by its ID. First insert wins.
67    pub fn add_plugin(&mut self, plugin: impl FreyaPlugin + 'static) {
68        self.plugins
69            .borrow_mut()
70            .entry(plugin.plugin_id())
71            .or_insert(Box::new(plugin));
72    }
73
74    pub fn send(&mut self, mut event: PluginEvent, handle: PluginHandle) {
75        for plugin in self.plugins.borrow_mut().values_mut() {
76            plugin.on_event(&mut event, handle.clone())
77        }
78    }
79}
80
81/// Event emitted to Plugins.
82pub enum PluginEvent<'a> {
83    /// A runner just got created.
84    RunnerCreated {
85        runner: &'a mut Runner,
86    },
87    /// A Window just got created.
88    WindowCreated {
89        window: &'a Window,
90        font_collection: &'a FontCollection,
91        tree: &'a Tree,
92        animation_clock: &'a AnimationClock,
93        runner: &'a mut Runner,
94        graphics_driver: &'static str,
95    },
96
97    /// A Window just got closed.
98    WindowClosed {
99        window: &'a Window,
100        tree: &'a Tree,
101    },
102
103    /// After having rendered, presented and everything else.
104    AfterRedraw {
105        window: &'a Window,
106        font_collection: &'a FontCollection,
107        tree: &'a Tree,
108    },
109
110    /// Before presenting the canvas to the window.
111    BeforePresenting {
112        window: &'a Window,
113        font_collection: &'a FontCollection,
114        tree: &'a Tree,
115    },
116
117    /// After presenting the canvas to the window.
118    AfterPresenting {
119        window: &'a Window,
120        font_collection: &'a FontCollection,
121        tree: &'a Tree,
122    },
123
124    /// Before starting to render the app to the Canvas.
125    BeforeRender {
126        window: &'a Window,
127        canvas: &'a Canvas,
128        font_collection: &'a FontCollection,
129        tree: &'a Tree,
130    },
131
132    /// After rendering the app to the Canvas.
133    AfterRender {
134        window: &'a Window,
135        canvas: &'a Canvas,
136        font_collection: &'a FontCollection,
137        tree: &'a Tree,
138        animation_clock: &'a AnimationClock,
139    },
140
141    /// Before starting to measure the layout.
142    StartedMeasuringLayout {
143        window: &'a Window,
144        tree: &'a Tree,
145    },
146
147    /// After measuringg the layout.
148    FinishedMeasuringLayout {
149        window: &'a Window,
150        tree: &'a Tree,
151    },
152
153    /// Before starting to process the queued events.
154    StartedMeasuringEvents {
155        window: &'a Window,
156        tree: &'a Tree,
157    },
158
159    /// After processing the queued events.
160    FinishedMeasuringEvents {
161        window: &'a Window,
162        tree: &'a Tree,
163    },
164
165    StartedUpdatingTree {
166        window: &'a Window,
167        tree: &'a Tree,
168    },
169
170    FinishedUpdatingTree {
171        window: &'a Window,
172        tree: &'a Tree,
173    },
174
175    BeforeAccessibility {
176        window: &'a Window,
177        font_collection: &'a FontCollection,
178        tree: &'a Tree,
179    },
180
181    AfterAccessibility {
182        window: &'a Window,
183        font_collection: &'a FontCollection,
184        tree: &'a Tree,
185    },
186
187    /// A keyboard input was received.
188    KeyboardInput {
189        window: &'a Window,
190        key: Key,
191        code: Code,
192        modifiers: Modifiers,
193        is_pressed: bool,
194    },
195}
196
197/// Skeleton for Freya plugins.
198pub trait FreyaPlugin {
199    /// Unique identifier for this plugin. Used for deduplication.
200    fn plugin_id(&self) -> &'static str;
201
202    /// React on events emitted by Freya.
203    fn on_event(&mut self, event: &mut PluginEvent, handle: PluginHandle);
204}