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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Internal and external event system
//!
//!
//! This is all kinda WIP, but the bones are there.
use crate::;
use ;
pub
/// User Events are events that are shuttled from the renderer into the VirtualDom through the scheduler channel.
///
/// These events will be passed to the appropriate Element given by `mounted_dom_id` and then bubbled up through the tree
/// where each listener is checked and fired if the event name matches.
///
/// It is the expectation that the event name matches the corresponding event listener, otherwise Dioxus will panic in
/// attempting to downcast the event data.
///
/// Because Event Data is sent across threads, it must be `Send + Sync`. We are hoping to lift the `Sync` restriction but
/// `Send` will not be lifted. The entire `UserEvent` must also be `Send + Sync` due to its use in the scheduler channel.
///
/// # Example
/// ```rust, ignore
/// fn App(cx: Scope) -> Element {
/// rsx!(cx, div {
/// onclick: move |_| println!("Clicked!")
/// })
/// }
///
/// let mut dom = VirtualDom::new(App);
/// let mut scheduler = dom.get_scheduler_channel();
/// scheduler.unbounded_send(SchedulerMsg::UiEvent(
/// UserEvent {
/// scope_id: None,
/// priority: EventPriority::Medium,
/// name: "click",
/// element: Some(ElementId(0)),
/// data: Arc::new(ClickEvent { .. })
/// }
/// )).unwrap();
/// ```
/// Priority of Event Triggers.
///
/// Internally, Dioxus will abort work that's taking too long if new, more important work arrives. Unlike React, Dioxus
/// won't be afraid to pause work or flush changes to the RealDOM. This is called "cooperative scheduling". Some Renderers
/// implement this form of scheduling internally, however Dioxus will perform its own scheduling as well.
///
/// The ultimate goal of the scheduler is to manage latency of changes, prioritizing "flashier" changes over "subtler" changes.
///
/// React has a 5-tier priority system. However, they break things into "Continuous" and "Discrete" priority. For now,
/// we keep it simple, and just use a 3-tier priority system.
///
/// - NoPriority = 0
/// - LowPriority = 1
/// - NormalPriority = 2
/// - UserBlocking = 3
/// - HighPriority = 4
/// - ImmediatePriority = 5
///
/// We still have a concept of discrete vs continuous though - discrete events won't be batched, but continuous events will.
/// This means that multiple "scroll" events will be processed in a single frame, but multiple "click" events will be
/// flushed before proceeding. Multiple discrete events is highly unlikely, though.
/// The internal Dioxus type that carries any event data to the relevant handler.
///
///
///
///
///
/// A UiEvent is a type that wraps various EventData.
///
/// You should prefer to use the name of the event directly, rather than
/// the UiEvent<T> generic type.
///
/// For the HTML crate, this would include [`MouseEvent`], [`FormEvent`] etc.