1use crate::app::info::AppInfo;
2use crate::app::update::UpdateManager;
3use crate::config::MayConfig;
4use indexmap::IndexMap;
5use maycoon_theme::theme::Theme;
6use std::sync::Arc;
7use std::time::Instant;
8use taffy::{NodeId, TaffyTree};
9use vello::util::{RenderContext, RenderSurface};
10use vello::{Renderer, Scene};
11use winit::event::WindowEvent;
12use winit::event_loop::{ActiveEventLoop, EventLoop};
13use winit::window::{Window, WindowAttributes};
14
15pub trait Plugin<T: Theme> {
22 fn name(&self) -> &'static str;
26
27 fn on_register(&mut self, _manager: &mut PluginManager<T>) {}
29
30 fn on_unregister(&mut self, _manager: &mut PluginManager<T>) {}
32
33 fn init(
35 &mut self,
36 _event_loop: &mut EventLoop<()>,
37 _update: &UpdateManager,
38 _window: &mut WindowAttributes,
39 _config: &mut MayConfig<T>,
40 ) {
41 }
42
43 fn on_resume(
48 &mut self,
49 _config: &mut MayConfig<T>,
50 _scene: &mut Scene,
51 _taffy: &mut TaffyTree,
52 _window_node: NodeId,
53 _info: &mut AppInfo,
54 _update: &UpdateManager,
55 _last_update: &mut Instant,
56 _event_loop: &ActiveEventLoop,
57 ) {
58 }
59
60 fn on_update(
63 &mut self,
64 _config: &mut MayConfig<T>,
65 _window: &Arc<Window>,
66 _renderer: &mut Renderer,
67 _scene: &mut Scene,
68 _surface: &mut RenderSurface<'_>,
69 _taffy: &mut TaffyTree,
70 _window_node: NodeId,
71 _info: &mut AppInfo,
72 _render_ctx: &mut RenderContext,
73 _update: &UpdateManager,
74 _last_update: &mut Instant,
75 _event_loop: &ActiveEventLoop,
76 ) {
77 }
78
79 fn on_window_event(
81 &mut self,
82 _event: &mut WindowEvent,
83 _config: &mut MayConfig<T>,
84 _window: &Arc<Window>,
85 _renderer: &mut Renderer,
86 _scene: &mut Scene,
87 _surface: &mut RenderSurface<'_>,
88 _taffy: &mut TaffyTree,
89 _window_node: NodeId,
90 _info: &mut AppInfo,
91 _render_ctx: &mut RenderContext,
92 _update: &UpdateManager,
93 _last_update: &mut Instant,
94 _event_loop: &ActiveEventLoop,
95 ) {
96 }
97
98 fn on_suspended(
100 &mut self,
101 _config: &mut MayConfig<T>,
102 _scene: &mut Scene,
103 _taffy: &mut TaffyTree,
104 _window_node: NodeId,
105 _info: &mut AppInfo,
106 _update: &UpdateManager,
107 _last_update: &mut Instant,
108 _event_loop: &ActiveEventLoop,
109 ) {
110 }
111}
112
113pub struct PluginManager<T: Theme> {
115 plugins: IndexMap<&'static str, Box<dyn Plugin<T>>>,
116}
117
118impl<T: Theme> PluginManager<T> {
119 pub fn new() -> Self {
121 Self {
122 plugins: IndexMap::new(),
123 }
124 }
125
126 pub fn register(&mut self, mut plugin: impl Plugin<T> + 'static) {
128 plugin.on_register(self);
129
130 self.plugins.insert(plugin.name(), Box::new(plugin));
131 }
132
133 pub fn unregister(&mut self, name: &'static str) {
135 let mut pl = self.plugins.swap_remove(name).expect("Plugin not found");
136
137 pl.on_unregister(self);
138 }
139
140 pub fn clear(&mut self) {
142 let plugins = self.plugins.keys().cloned().collect::<Vec<_>>();
143
144 for name in plugins {
145 self.unregister(name);
146 }
147 }
148
149 pub fn run<F>(&mut self, mut op: F)
151 where
152 F: FnMut(&mut Box<dyn Plugin<T>>),
153 {
154 for pl in self.plugins.values_mut() {
155 op(pl);
156 }
157 }
158}
159
160impl<T: Theme> Default for PluginManager<T> {
161 fn default() -> Self {
162 Self::new()
163 }
164}