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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
use winit::{
dpi::{
LogicalSize,
PhysicalSize,
},
event::Event,
event_loop::{
ControlFlow,
EventLoop,
EventLoopBuilder,
EventLoopProxy,
EventLoopWindowTarget,
},
monitor::MonitorHandle,
window::{
Window,
WindowBuilder,
},
};
pub mod winit_exports {
pub use winit::{
event::{
ElementState,
Event,
VirtualKeyCode,
WindowEvent,
},
event_loop::{
ControlFlow,
EventLoop,
EventLoopProxy,
EventLoopWindowTarget,
},
};
}
pub struct LoopBuilder;
impl LoopBuilder {
pub fn new() -> Self {
return Self;
}
pub fn build<Events: 'static + std::fmt::Debug>(self) -> Loop<Events> {
let event_loop = EventLoopBuilder::<Events>::with_user_event().build();
return Loop { event_loop };
}
}
pub struct Loop<E: 'static + std::fmt::Debug> {
event_loop: EventLoop<E>,
}
pub struct WindowProperties {
pub name: String,
pub dimensions: (u32, u32),
pub monitor_handle: MonitorHandle,
}
#[derive(Clone, Copy)]
pub struct WindowSize {
pub width: u32,
pub height: u32,
pub logical: LogicalSize<u32>,
pub physical: PhysicalSize<u32>,
}
pub struct WindowHandle {
pub window_handle: Window,
pub size: WindowSize,
pub monitor_handle: MonitorHandle,
}
pub struct WindowHandleBuilder {
window_handle: Option<Window>,
size: WindowSize,
monitor_handle: Option<MonitorHandle>,
}
impl WindowHandleBuilder {
pub fn new() -> Self {
let logical: LogicalSize<u32> = [0, 0].into();
let physical = logical.to_physical(1.0);
let size = WindowSize {
width: 0,
height: 0,
logical,
physical,
};
return Self {
window_handle: None,
size,
monitor_handle: None,
};
}
fn with_window_size(
mut self,
window_size: (u32, u32),
scale_factor: f64,
) -> Self {
let logical: LogicalSize<u32> = window_size.into();
let physical: PhysicalSize<u32> = logical.to_physical(scale_factor);
let (width, height) = window_size;
let window_size = WindowSize {
width,
height,
logical,
physical,
};
self.size = window_size;
return self;
}
pub fn with_window_properties<E: 'static + std::fmt::Debug>(
mut self,
window_properties: WindowProperties,
lambda_loop: &Loop<E>,
) -> Self {
let WindowProperties {
name,
dimensions,
monitor_handle,
} = window_properties;
self = self.with_window_size(dimensions, monitor_handle.scale_factor());
let window_handle = WindowBuilder::new()
.with_title(name)
.with_inner_size(self.size.logical)
.build(&lambda_loop.event_loop)
.expect("Failed creation of window handle");
self.monitor_handle = Some(monitor_handle);
self.window_handle = Some(window_handle);
return self;
}
pub fn build(self) -> WindowHandle {
return WindowHandle {
monitor_handle: self
.monitor_handle
.expect("Unable to find a MonitorHandle."),
size: self.size,
window_handle: self.window_handle.expect("Unable to find WindowHandle."),
};
}
}
pub struct LoopPublisher<E: 'static> {
winit_proxy: EventLoopProxy<E>,
}
impl<E: 'static + std::fmt::Debug> LoopPublisher<E> {
#[inline]
pub fn new(lambda_loop: &Loop<E>) -> Self {
let winit_proxy = lambda_loop.event_loop.create_proxy();
return LoopPublisher { winit_proxy };
}
#[inline]
pub fn publish_event(&self, event: E) {
self
.winit_proxy
.send_event(event)
.expect("Failed to send event");
}
}
impl<E: 'static + std::fmt::Debug> Loop<E> {
pub fn create_event_publisher(&mut self) -> LoopPublisher<E> {
return LoopPublisher::new(&self);
}
pub fn get_primary_monitor(&self) -> Option<MonitorHandle> {
return self.event_loop.primary_monitor();
}
pub fn get_all_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
return self.event_loop.available_monitors();
}
pub fn get_any_available_monitors(&self) -> Option<MonitorHandle> {
return self.event_loop.available_monitors().next();
}
pub fn run_forever<Callback>(self, callback: Callback)
where
Callback: 'static
+ FnMut(Event<E>, &EventLoopWindowTarget<E>, &mut ControlFlow) -> (),
{
self.event_loop.run(callback);
}
}