I wan't to know when every event occurs so I'm moving my window into another thread, using run_forever on the event loop with a callback that passes every event along with a std::time::Instant to the window thread.
When I call gl_window.make_current the thread blocks until I move my mouse or after I fire a couple of keyboard input events.
I'm on linux and the backend seems to be X.
I have no idea how event loops work internally. I don't know what it means to "wake up the event loop". I know this has been mentioned before like in #239 and #420.
The glutin documentation says the following:
Note that the EventsLoop cannot be shared accross threads (due to platform-dependant logic forbiding it), as such it is neither Send nor Sync. If you need cross-thread access, the Window created from this EventsLoop can be sent to an other thread, and the EventsLoopProxy allows you to wakeup an EventsLoop from an other thread.
The code
use glutin;
use glutin::GlContext;
use std::sync::mpsc;
use std::thread;
use std::time;
mod gl;
fn main() {
let start = time::Instant::now();
let window_dims = glutin::dpi::LogicalSize::new(640.0, 480.0);
let mut event_loop = glutin::EventsLoop::new();
let gl_window = glutin::GlWindow::new(
glutin::WindowBuilder::new()
.with_title("Continuous event loop")
.with_dimensions(window_dims),
glutin::ContextBuilder::new()
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (4, 5)))
.with_gl_profile(glutin::GlProfile::Core),
&event_loop,
)
.unwrap();
#[derive(Debug)]
struct TimedEvent {
instant: time::Instant,
event: glutin::Event,
};
let (timed_event_tx, timed_event_rx) = mpsc::channel::<TimedEvent>();
let _guard = thread::spawn(move || {
let mut should_keep_running = true;
println!("{:?}", start.elapsed());
unsafe {
gl_window.make_current().unwrap();
}
println!("{:?}", start.elapsed());
let gl = gl::Gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _);
println!("{:?}", start.elapsed());
while should_keep_running {
// Process input.
for timed_event in timed_event_rx.try_iter() {
let TimedEvent { instant, event } = timed_event;
println!("{:?} {:?}", instant.elapsed(), event);
use glutin::Event;
match event {
Event::DeviceEvent { event, .. } => {
use glutin::DeviceEvent;
match event {
DeviceEvent::Key(keyboard_input) => {
if let Some(virtual_keycode) = keyboard_input.virtual_keycode {
use glutin::VirtualKeyCode;
match virtual_keycode {
VirtualKeyCode::Escape => {
should_keep_running = false;
}
_ => {}
}
}
}
_ => {}
}
}
_ => {}
}
}
// Render.
unsafe {
gl.ClearColor(0.7, 0.8, 0.9, 1.0);
gl.Clear(gl::COLOR_BUFFER_BIT);
}
// VSync.
gl_window.swap_buffers().unwrap();
}
});
event_loop.run_forever(|event| {
match timed_event_tx.send(TimedEvent {
instant: time::Instant::now(),
event,
}) {
Ok(_) => glutin::ControlFlow::Continue,
Err(_) => glutin::ControlFlow::Break,
}
})
}
The output (started moving my mouse after ~4 seconds):
45.166266ms
4.461137718s
4.462550974s
4.416836559s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: Resized(LogicalSize { width: 640.0, height: 480.0 }) }
4.41684652s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: Moved(LogicalPosition { x: 63.333333333333336, y: 36.666666666666664 }) }
4.416853051s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: Refresh }
4.416806095s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: CursorEntered { device_id: DeviceId(X(DeviceId(2))) } }
4.416798429s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: CursorMoved { device_id: DeviceId(X(DeviceId(2))), position: LogicalPosition { x: 360.6666666666667, y: 84.66666666666667 }, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
4.416733053s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: Focused(true) }
4.416736955s WindowEvent { window_id: WindowId(X(WindowId(52428805))), event: CursorMoved { device_id: DeviceId(X(DeviceId(2))), position: LogicalPosition { x: 360.6666666666667, y: 84.66666666666667 }, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
34.678495ms DeviceEvent { device_id: DeviceId(X(DeviceId(12))), event: Motion { axis: 0, value: 0.0 } }
Is there a way to make this work?
I wan't to know when every event occurs so I'm moving my window into another thread, using
run_foreveron the event loop with a callback that passes every event along with astd::time::Instantto the window thread.When I call
gl_window.make_currentthe thread blocks until I move my mouse or after I fire a couple of keyboard input events.I'm on linux and the backend seems to be X.
I have no idea how event loops work internally. I don't know what it means to "wake up the event loop". I know this has been mentioned before like in #239 and #420.
The glutin documentation says the following:
The code
The output (started moving my mouse after ~4 seconds):
Is there a way to make this work?