makepad_platform/os/windows/
windows_stdin.rs1use {
2 std::{
3 io,
4 io::prelude::*,
5 io::BufReader,
6 },
7 crate::{
8 makepad_live_id::*,
9 makepad_math::*,
10 makepad_error_log::*,
11 makepad_micro_serde::*,
12 makepad_live_compiler::LiveFileChange,
13 event::Event,
14 window::CxWindowPool,
15 event::WindowGeom,
16 texture::{Texture, TextureDesc, TextureFormat},
17 live_traits::LiveNew,
18 thread::Signal,
19 os::{
20 d3d11::D3d11Cx,
21 cx_stdin::{HostToStdin, PresentableDraw, StdinToHost, Swapchain},
22 },
23 pass::{CxPassParent, PassClearColor, CxPassColorTexture},
24 cx_api::CxOsOp,
25 cx::Cx,
26 windows::Win32::Foundation::HANDLE,
27 }
28};
29
30impl Cx {
31
32 pub (crate) fn stdin_handle_repaint(
33 &mut self,
34 d3d11_cx: &mut D3d11Cx,
35 swapchain: Option<&Swapchain<Texture >>,
36 present_index: &mut usize,
37 ) {
38 let mut passes_todo = Vec::new();
39 self.compute_pass_repaint_order(&mut passes_todo);
40 self.repaint_id += 1;
41 for &pass_id in &passes_todo {
42 match self.passes[pass_id].parent.clone() {
43 CxPassParent::Window(_) => {
44 if let Some(swapchain) = swapchain {
46
47 if self.os.new_frame_being_rendered.is_none() {
49 let current_image = &swapchain.presentable_images[*present_index];
50 *present_index = (*present_index + 1) % swapchain.presentable_images.len();
51
52 self.draw_pass_to_texture(pass_id, d3d11_cx, current_image.image.texture_id());
54
55 let dpi_factor = self.passes[pass_id].dpi_factor.unwrap();
56 let pass_rect = self.get_pass_rect(pass_id, dpi_factor).unwrap();
57 let future_presentable_draw = PresentableDraw {
58 target_id: current_image.id,
59 width: (pass_rect.size.x * dpi_factor) as u32,
60 height: (pass_rect.size.y * dpi_factor) as u32,
61 };
62
63 d3d11_cx.start_querying();
65
66 self.os.new_frame_being_rendered = Some(future_presentable_draw);
68 }
69 }
70 }
71 CxPassParent::Pass(_) => {
72 self.draw_pass_to_magic_texture(pass_id, d3d11_cx);
74 },
75 CxPassParent::None => {
76 self.draw_pass_to_magic_texture(pass_id, d3d11_cx);
77 }
78 }
79 }
80 }
81
82 pub fn stdin_event_loop(&mut self, d3d11_cx: &mut D3d11Cx) {
83
84 let (json_msg_tx, json_msg_rx) = std::sync::mpsc::channel();
85 {
86 std::thread::spawn(move || {
87 let mut reader = BufReader::new(std::io::stdin().lock());
88 let mut line = String::new();
89 loop {
90 line.clear();
91 if let Ok(0) | Err(_) = reader.read_line(&mut line) {
92 break;
93 }
94
95 match HostToStdin::deserialize_json(&line) {
97 Ok(msg) => {
98 if json_msg_tx.send(msg).is_err() {
99 break;
100 }
101 }
102 Err(err) => {
103 error!("Cant parse stdin-JSON {} {:?}", line, err)
105 }
106 }
107 }
108 });
109 }
110
111 let _ = io::stdout().write_all(StdinToHost::ReadyToStart.to_json().as_bytes());
112
113 let mut swapchain = None;
114 let mut present_index = 0;
115
116 self.call_event_handler(&Event::Construct);
117
118 while let Ok(msg) = json_msg_rx.recv() {
119 match msg {
120 HostToStdin::ReloadFile {file, contents} => {
121 let _ = self.live_file_change_sender.send(vec![LiveFileChange {
123 file_name: file,
124 content: contents
125 }]);
126 }
127 HostToStdin::KeyDown(e) => {
128 self.call_event_handler(&Event::KeyDown(e));
129 }
130 HostToStdin::KeyUp(e) => {
131 self.call_event_handler(&Event::KeyUp(e));
132 }
133 HostToStdin::MouseDown(e) => {
134 self.fingers.process_tap_count(
135 dvec2(e.x, e.y),
136 e.time
137 );
138 self.fingers.mouse_down(e.button);
139
140 self.call_event_handler(&Event::MouseDown(e.into()));
141 }
142 HostToStdin::MouseMove(e) => {
143 self.call_event_handler(&Event::MouseMove(e.into()));
144 self.fingers.cycle_hover_area(live_id!(mouse).into());
145 self.fingers.switch_captures();
146 }
147 HostToStdin::MouseUp(e) => {
148 let button = e.button;
149 self.call_event_handler(&Event::MouseUp(e.into()));
150 self.fingers.mouse_up(button);
151 self.fingers.cycle_hover_area(live_id!(mouse).into());
152 }
153 HostToStdin::Scroll(e) => {
154 self.call_event_handler(&Event::Scroll(e.into()))
155 }
156 HostToStdin::WindowGeomChange { dpi_factor, inner_width, inner_height } => {
157 self.windows[CxWindowPool::id_zero()].window_geom = WindowGeom {
158 dpi_factor,
159 inner_size: dvec2(inner_width, inner_height),
160 ..Default::default()
161 };
162 self.redraw_all();
163 }
164 HostToStdin::Swapchain(new_swapchain) => {
165 let new_swapchain = new_swapchain.images_map(|pi| {
166 let handle = HANDLE(pi.image as isize);
167
168 let texture = Texture::new(self);
169 let desc = TextureDesc {
170 format: TextureFormat::SharedBGRA(pi.id),
171 width: Some(new_swapchain.alloc_width as usize),
172 height: Some(new_swapchain.alloc_height as usize),
173 };
174 texture.set_desc(self, desc);
175 self.textures[texture.texture_id()]
176 .os.update_from_shared_handle(d3d11_cx, handle);
177 texture
178 });
179 let swapchain = swapchain.insert(new_swapchain);
180
181 present_index = 0;
183
184 self.redraw_all();
185 self.stdin_handle_platform_ops(Some(swapchain), present_index);
186 }
187 HostToStdin::Tick {frame: _, time, ..} => if swapchain.is_some() {
188
189 if Signal::check_and_clear_ui_signal() {
192 self.handle_media_signals();
193 self.call_event_handler(&Event::Signal);
194 }
195 if self.handle_live_edit() {
196 self.call_event_handler(&Event::LiveEdit);
197 self.redraw_all();
198 }
199 self.handle_networking_events();
200 self.stdin_handle_platform_ops(swapchain.as_ref(), present_index);
202
203 if self.new_next_frames.len() != 0 {
206 self.call_next_frame_event(time);
207 }
208
209 if self.need_redrawing() {
210 self.call_draw_event();
211 self.hlsl_compile_shaders(d3d11_cx);
212 }
213
214 self.stdin_handle_repaint(d3d11_cx, swapchain.as_ref(), &mut present_index);
216
217
218 if let Some(presentable_draw) = self.os.new_frame_being_rendered {
220 while !d3d11_cx.is_gpu_done() {
221 std::thread::sleep(std::time::Duration::from_millis(3));
222 }
223 let _ = io::stdout().write_all(StdinToHost::DrawCompleteAndFlip(presentable_draw).to_json().as_bytes());
224 self.os.new_frame_being_rendered = None;
225 }
226
227 }
228 }
229 }
230 }
231
232 fn stdin_handle_platform_ops(
233 &mut self,
234 swapchain: Option<&Swapchain<Texture >>,
235 present_index: usize,
236 ) {
237 while let Some(op) = self.platform_ops.pop() {
238 match op {
239 CxOsOp::CreateWindow(window_id) => {
240 if window_id != CxWindowPool::id_zero() {
241 panic!("ONLY ONE WINDOW SUPPORTED");
242 }
243 let window = &mut self.windows[CxWindowPool::id_zero()];
244 window.is_created = true;
245 let pass = &mut self.passes[window.main_pass_id.unwrap()];
247 if let Some(swapchain) = swapchain {
248 pass.color_textures = vec![CxPassColorTexture {
249 clear_color: PassClearColor::ClearWith(vec4(1.0, 1.0, 0.0, 1.0)),
250 texture_id: swapchain.presentable_images[present_index].image.texture_id(),
252 }];
253 }
254 },
255 CxOsOp::SetCursor(cursor) => {
256 let _ = io::stdout().write_all(StdinToHost::SetCursor(cursor).to_json().as_bytes());
257 },
258 _ => ()
259 }
277 }
278 }
279
280}