makepad_platform/os/
cx_shared.rs1use {
2 std::collections::{HashSet, HashMap},
3 crate::{
4 cx_api::CxOsApi,
5 cx::Cx,
6 pass::{
7 PassId,
8 CxPassParent
9 },
10 event::{
11 TimerEvent,
12 DrawEvent,
13 TriggerEvent,
14 Event,
15 KeyFocusEvent,
16 NextFrameEvent,
17 },
18 studio::{AppToStudio,EventSample},
19 }
20};
21
22impl Cx {
23 #[allow(dead_code)]
24 pub (crate) fn repaint_windows(&mut self) {
25 for pass_id in self.passes.id_iter() {
26 match self.passes[pass_id].parent {
27 CxPassParent::Window(_) => {
28 self.passes[pass_id].paint_dirty = true;
29 },
30 _ => ()
31 }
32 }
33 }
34
35 #[allow(unused)]
36 pub (crate) fn any_passes_dirty(&self) -> bool {
37 for pass_id in self.passes.id_iter() {
38 if self.passes[pass_id].paint_dirty {
39 return true
40 }
41 }
42 false
43 }
44
45 pub (crate) fn compute_pass_repaint_order(&mut self, passes_todo: &mut Vec<PassId>) {
46 passes_todo.clear();
47
48 loop { let mut altered = false;
51 for pass_id in self.passes.id_iter(){
52 if self.demo_time_repaint {
53 if self.passes[pass_id].main_draw_list_id.is_some(){
54 self.passes[pass_id].paint_dirty = true;
55 }
56 }
57 if self.passes[pass_id].paint_dirty {
58 let other = match self.passes[pass_id].parent {
59 CxPassParent::Pass(parent_pass_id) => {
60 Some(parent_pass_id)
61 }
62 _ => None
63 };
64 if let Some(other) = other {
65 if !self.passes[other].paint_dirty {
66 self.passes[other].paint_dirty = true;
67 altered = true;
68 }
69 }
70 }
71 }
72 if !altered {
73 break
74 }
75 }
76
77 for pass_id in self.passes.id_iter(){
78 if self.passes[pass_id].paint_dirty {
79 let mut inserted = false;
80 match self.passes[pass_id].parent {
81 CxPassParent::Window(_) | CxPassParent::Xr=> {
82 },
83 CxPassParent::Pass(dep_of_pass_id) => {
84 if pass_id == dep_of_pass_id {
85 panic!()
86 }
87 for insert_before in 0..passes_todo.len() {
88 if passes_todo[insert_before] == dep_of_pass_id {
89 passes_todo.insert(insert_before, pass_id);
90 inserted = true;
91 break;
92 }
93 }
94 },
95 CxPassParent::None => { passes_todo.insert(0, pass_id);
97 inserted = true;
98 },
99 }
100 if !inserted {
101 passes_todo.push(pass_id);
102 }
103 }
104 }
105 self.demo_time_repaint = false;
106 }
107
108 pub (crate) fn need_redrawing(&self) -> bool {
109 self.new_draw_event.will_redraw()
110 }
111
112
113
114
115 pub (crate) fn inner_call_event_handler(&mut self, event: &Event) {
119 self.event_id += 1;
120 if Cx::has_studio_web_socket(){
121 let start = self.seconds_since_app_start();
122 let mut event_handler = self.event_handler.take().unwrap();
123 event_handler(self, event);
124 self.event_handler = Some(event_handler);
125 let end = self.seconds_since_app_start();
126 Cx::send_studio_message(AppToStudio::EventSample(EventSample{
127 event_u32: event.to_u32(),
128 start: start,
129 event_meta: if let Event::Timer(TimerEvent{timer_id,..}) = event{*timer_id}else{0},
130 end: end
131 }))
132 }
133 else{
134 let mut event_handler = self.event_handler.take().unwrap();
135 event_handler(self, event);
136 self.event_handler = Some(event_handler);
137 }
138
139 if let Some(event_id) = self.widget_query_invalidation_event {
144 if self.event_id > event_id + 1 {
145 self.widget_query_invalidation_event = None;
146 }
147 }
148 }
149
150 fn inner_key_focus_change(&mut self) {
151 if let Some((prev, focus)) = self.keyboard.cycle_key_focus_changed(){
152 self.inner_call_event_handler(&Event::KeyFocus(KeyFocusEvent {
153 prev,
154 focus
155 }));
156 }
157 }
158
159 pub fn handle_triggers(&mut self) {
160 let mut counter = 0;
162 while self.triggers.len() != 0 {
163 counter += 1;
164 let mut triggers = HashMap::new();
165 std::mem::swap(&mut self.triggers, &mut triggers);
166 self.inner_call_event_handler(&Event::Trigger(TriggerEvent {
167 triggers: triggers,
168 }));
169 self.inner_key_focus_change();
170 if counter > 100 {
171 crate::error!("Trigger feedback loop detected");
172 break
173 }
174 }
175 }
176
177 pub fn handle_actions(&mut self) {
178 let mut counter = 0;
180 while self.new_actions.len() != 0 {
181 counter += 1;
182 let mut actions = Vec::new();
183 std::mem::swap(&mut self.new_actions, &mut actions);
184 self.inner_call_event_handler(&Event::Actions(actions));
185 self.inner_key_focus_change();
186 if counter > 100 {
187 crate::error!("Action feedback loop detected");
188 crate::error!("New actions {:#?}", self.new_actions);
189 break
190 }
191 }
192 }
193
194 pub (crate) fn call_event_handler(&mut self, event: &Event) {
195 self.inner_call_event_handler(event);
196 self.inner_key_focus_change();
197 self.handle_triggers();
198 self.handle_actions();
199 }
200
201 pub (crate) fn call_draw_event(&mut self) {
212 let mut draw_event = DrawEvent::default();
213 std::mem::swap(&mut draw_event, &mut self.new_draw_event);
214 self.in_draw_event = true;
215
216 self.call_event_handler(&Event::Draw(draw_event));
217 self.in_draw_event = false;
218 }
219
220 pub (crate) fn call_next_frame_event(&mut self, time: f64) {
221 let mut set = HashSet::default();
222 std::mem::swap(&mut set, &mut self.new_next_frames);
223
224 self.performance_stats.process_frame_data(time);
225
226 self.call_event_handler(&Event::NextFrame(NextFrameEvent {set, time: time, frame: self.repaint_id}));
227 }
228}