freya_core/
plugins.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use std::{
    cell::RefCell,
    rc::Rc,
};

use freya_engine::prelude::{
    Canvas,
    FontCollection,
};
use winit::{
    event_loop::EventLoopProxy,
    window::{
        Window,
        WindowId,
    },
};

use crate::{
    dom::FreyaDOM,
    event_loop_messages::{
        EventLoopMessage,
        EventLoopMessageAction,
    },
    events::PlatformEvent,
};

#[derive(Clone)]
pub struct PluginHandle {
    pub proxy: EventLoopProxy<EventLoopMessage>,
}

impl PluginHandle {
    pub fn new(proxy: &EventLoopProxy<EventLoopMessage>) -> Self {
        Self {
            proxy: proxy.clone(),
        }
    }

    /// Emit a [PlatformEvent]. Useful to simulate certain events.
    pub fn send_platform_event(&self, event: PlatformEvent, window_id: WindowId) {
        self.proxy
            .send_event(EventLoopMessage {
                window_id: Some(window_id),
                action: EventLoopMessageAction::PlatformEvent(event),
            })
            .ok();
    }

    /// Emit a [EventLoopMessage].
    pub fn send_event_loop_event(&self, event: EventLoopMessage) {
        self.proxy.send_event(event).ok();
    }
}

/// Manages all loaded plugins.
#[derive(Default, Clone)]
pub struct PluginsManager {
    plugins: Rc<RefCell<Vec<Box<dyn FreyaPlugin>>>>,
}

impl PluginsManager {
    pub fn add_plugin(&mut self, plugin: impl FreyaPlugin + 'static) {
        self.plugins.borrow_mut().push(Box::new(plugin))
    }

    pub fn send(&mut self, event: PluginEvent, handle: PluginHandle) {
        for plugin in self.plugins.borrow_mut().iter_mut() {
            plugin.on_event(&event, handle.clone())
        }
    }
}

/// Event emitted to Plugins.
pub enum PluginEvent<'a> {
    /// A Window just got created.
    WindowCreated {
        window: &'a Window,
        canvas: &'a Canvas,
        font_collection: &'a FontCollection,
        fdom: &'a FreyaDOM,
    },

    /// A Window just got closed.
    WindowClosed {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    /// Before starting to render the app to the Canvas.
    BeforeRender {
        window: &'a Window,
        canvas: &'a Canvas,
        font_collection: &'a FontCollection,
        fdom: &'a FreyaDOM,
    },

    /// After rendering the app to the Canvas.
    AfterRender {
        window: &'a Window,
        canvas: &'a Canvas,
        font_collection: &'a FontCollection,
        fdom: &'a FreyaDOM,
    },

    /// Before starting to measure the layout.
    StartedMeasuringLayout {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    /// After measuring the layout.
    FinishedMeasuringLayout {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    /// Before starting to process the queued events.
    StartedMeasuringEvents {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    /// After processing the queued events.
    FinishedMeasuringEvents {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    StartedUpdatingDOM {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },

    FinishedUpdatingDOM {
        window: &'a Window,
        fdom: &'a FreyaDOM,
    },
}

/// Skeleton for Freya plugins.
pub trait FreyaPlugin {
    /// React on events emitted by Freya.
    fn on_event(&mut self, event: &PluginEvent, handle: PluginHandle);
}