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
use crate::{config::DisplayConfig, resources::ScreenDimensions};
use amethyst_config::Config;
use amethyst_core::{
ecs::{ReadExpect, RunNow, System, SystemData, World, Write, WriteExpect},
shrev::EventChannel,
};
use std::path::Path;
use winit::{Event, EventsLoop, Window};
#[derive(Debug)]
pub struct WindowSystem;
impl WindowSystem {
pub fn from_config_path(
world: &mut World,
events_loop: &EventsLoop,
path: impl AsRef<Path>,
) -> Self {
Self::from_config(world, events_loop, DisplayConfig::load(path.as_ref()))
}
pub fn from_config(world: &mut World, events_loop: &EventsLoop, config: DisplayConfig) -> Self {
let window = config
.into_window_builder(events_loop)
.build(events_loop)
.unwrap();
Self::new(world, window)
}
pub fn new(world: &mut World, window: Window) -> Self {
let (width, height) = window
.get_inner_size()
.expect("Window closed during initialization!")
.into();
let hidpi = window.get_hidpi_factor();
world.insert(ScreenDimensions::new(width, height, hidpi));
world.insert(window);
Self
}
fn manage_dimensions(&mut self, mut screen_dimensions: &mut ScreenDimensions, window: &Window) {
let width = screen_dimensions.w;
let height = screen_dimensions.h;
if screen_dimensions.dirty {
window.set_inner_size((width, height).into());
screen_dimensions.dirty = false;
}
let hidpi = window.get_hidpi_factor();
if let Some(size) = window.get_inner_size() {
let (window_width, window_height): (f64, f64) = size.to_physical(hidpi).into();
if (window_width, window_height) != (width, height) {
screen_dimensions.update(window_width, window_height);
screen_dimensions.dirty = false;
}
}
screen_dimensions.update_hidpi_factor(hidpi);
}
}
impl<'a> System<'a> for WindowSystem {
type SystemData = (WriteExpect<'a, ScreenDimensions>, ReadExpect<'a, Window>);
fn run(&mut self, (mut screen_dimensions, window): Self::SystemData) {
#[cfg(feature = "profiler")]
profile_scope!("window_system");
self.manage_dimensions(&mut screen_dimensions, &window);
}
}
#[derive(Debug)]
pub struct EventsLoopSystem {
events_loop: EventsLoop,
events: Vec<Event>,
}
impl EventsLoopSystem {
pub fn new(events_loop: EventsLoop) -> Self {
Self {
events_loop,
events: Vec::with_capacity(128),
}
}
}
impl<'a> RunNow<'a> for EventsLoopSystem {
fn run_now(&mut self, world: &'a World) {
let mut event_handler = <Write<'a, EventChannel<Event>>>::fetch(world);
let events = &mut self.events;
self.events_loop.poll_events(|event| {
events.push(event);
});
event_handler.drain_vec_write(events);
}
fn setup(&mut self, world: &mut World) {
<Write<'a, EventChannel<Event>>>::setup(world);
}
}