Open/close window events
This commit is contained in:
parent
63691ebc28
commit
e624edc36f
|
@ -9,4 +9,5 @@ glium = "0.32"
|
|||
magpie-types = { path = "../../crates/magpie-types" }
|
||||
mio = { version = "0.8", features = ["net", "os-poll"] }
|
||||
mio-signals = "0.2"
|
||||
parking_lot = "0.12"
|
||||
slab = "0.4"
|
||||
|
|
|
@ -3,12 +3,14 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::str::from_utf8;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use magpie_types::ServerMessenger;
|
||||
use magpie_types::{CreatePanel, MagpieClientMsg, MagpieServerMsg, ServerMessenger};
|
||||
use mio::net::{UnixListener, UnixStream};
|
||||
use mio::{Events, Interest, Poll, Token, Waker};
|
||||
use mio_signals::{Signal, Signals};
|
||||
use parking_lot::RwLock;
|
||||
use slab::Slab;
|
||||
|
||||
use crate::window::{WindowMessage, WindowMessageSender};
|
||||
|
@ -51,24 +53,31 @@ impl DerefMut for Listener {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct IpcData {
|
||||
poll: Poll,
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
data: Arc<RwLock<IpcData>>,
|
||||
window_sender: WindowMessageSender,
|
||||
messenger: ServerMessenger<UnixStream>,
|
||||
token: Token,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new(connection: UnixStream, token: Token) -> Self {
|
||||
Self {
|
||||
messenger: ServerMessenger::new(connection),
|
||||
token,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_readable(&mut self) -> std::io::Result<bool> {
|
||||
self.messenger.flush_recv()?;
|
||||
|
||||
while let Some(msg) = self.messenger.recv() {
|
||||
println!("Client #{}: {:?}", self.token.0, msg);
|
||||
match msg {
|
||||
MagpieServerMsg::CreatePanel(CreatePanel { id }) => {
|
||||
let id = id as usize;
|
||||
let msg = WindowMessage::OpenWindow { id };
|
||||
let _ = self.window_sender.send_event(msg);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.messenger.is_closed())
|
||||
|
@ -76,9 +85,9 @@ impl Client {
|
|||
}
|
||||
|
||||
pub struct Ipc {
|
||||
pub message_recv: Receiver<IpcMessage>,
|
||||
pub data: Arc<RwLock<IpcData>>,
|
||||
pub window_sender: WindowMessageSender,
|
||||
pub poll: Poll,
|
||||
pub message_recv: Receiver<IpcMessage>,
|
||||
pub events: Events,
|
||||
pub quit: bool,
|
||||
pub listener: Listener,
|
||||
|
@ -121,10 +130,12 @@ impl Ipc {
|
|||
sender,
|
||||
};
|
||||
|
||||
let data = IpcData { poll };
|
||||
|
||||
let ipc = Self {
|
||||
message_recv,
|
||||
data: Arc::new(RwLock::new(data)),
|
||||
window_sender,
|
||||
poll,
|
||||
message_recv,
|
||||
events,
|
||||
quit: false,
|
||||
listener,
|
||||
|
@ -139,7 +150,7 @@ impl Ipc {
|
|||
}
|
||||
|
||||
pub fn poll(&mut self, timeout: Option<Duration>) -> std::io::Result<()> {
|
||||
self.poll.poll(&mut self.events, timeout)?;
|
||||
self.data.write().poll.poll(&mut self.events, timeout)?;
|
||||
|
||||
for event in self.events.iter() {
|
||||
if event.token() == self.listener_token {
|
||||
|
@ -153,12 +164,18 @@ impl Ipc {
|
|||
);
|
||||
|
||||
let interest = Interest::READABLE;
|
||||
self.poll
|
||||
.registry()
|
||||
.register(&mut connection, token, interest)?;
|
||||
self.data.write().poll.registry().register(
|
||||
&mut connection,
|
||||
token,
|
||||
interest,
|
||||
)?;
|
||||
|
||||
let client = Client::new(connection, token);
|
||||
self.clients.insert(client);
|
||||
self.clients.insert(Client {
|
||||
messenger: ServerMessenger::new(connection),
|
||||
token,
|
||||
data: self.data.clone(),
|
||||
window_sender: self.window_sender.clone(),
|
||||
});
|
||||
}
|
||||
Err(ref err) if err.kind() == std::io::ErrorKind::WouldBlock => break,
|
||||
Err(err) => return Err(err),
|
||||
|
@ -175,7 +192,11 @@ impl Ipc {
|
|||
if disconnected {
|
||||
println!("Client #{} disconnected", event.token().0);
|
||||
let mut client = self.clients.remove(event.token().0);
|
||||
self.poll.registry().deregister(&mut client.messenger.transport)?;
|
||||
self.data
|
||||
.write()
|
||||
.poll
|
||||
.registry()
|
||||
.deregister(&mut client.messenger.transport)?;
|
||||
}
|
||||
} else {
|
||||
panic!("Unrecognized event token: {:?}", event);
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use glium::backend::glutin::DisplayCreationError;
|
||||
use glium::glutin;
|
||||
use glium::{glutin, Surface};
|
||||
use glutin::event::{Event, WindowEvent};
|
||||
use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy};
|
||||
use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
||||
use glutin::window::WindowId;
|
||||
|
||||
use crate::gl::Graphics;
|
||||
use crate::ipc::{IpcMessage, IpcMessageSender};
|
||||
|
||||
pub enum WindowMessage {
|
||||
OpenWindow { id: usize },
|
||||
CloseWindow { id: usize },
|
||||
Quit,
|
||||
}
|
||||
|
||||
|
@ -21,7 +23,9 @@ pub struct Window {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(event_loop: &EventLoop<()>) -> Result<Self, DisplayCreationError> {
|
||||
pub fn new(
|
||||
event_loop: &EventLoopWindowTarget<WindowMessage>,
|
||||
) -> Result<Self, DisplayCreationError> {
|
||||
let wb = glutin::window::WindowBuilder::new();
|
||||
let cb = glutin::ContextBuilder::new();
|
||||
let display = glium::Display::new(wb, cb, &event_loop)?;
|
||||
|
@ -29,10 +33,15 @@ impl Window {
|
|||
|
||||
Ok(Self { display, graphics })
|
||||
}
|
||||
|
||||
pub fn request_redraw(&mut self) {
|
||||
self.display.gl_window().window().request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WindowStore {
|
||||
pub ipc_sender: IpcMessageSender,
|
||||
pub ipc_to_window: HashMap<usize, WindowId>,
|
||||
pub windows: HashMap<WindowId, Window>,
|
||||
}
|
||||
|
||||
|
@ -40,23 +49,44 @@ impl WindowStore {
|
|||
pub fn new(ipc_sender: IpcMessageSender) -> Self {
|
||||
Self {
|
||||
ipc_sender,
|
||||
ipc_to_window: Default::default(),
|
||||
windows: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(self, event_loop: EventLoop<WindowMessage>) -> ! {
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::WindowEvent { window_id, event } => match event {
|
||||
_ => {}
|
||||
},
|
||||
Event::MainEventsCleared => {}
|
||||
Event::UserEvent(event) => match event {
|
||||
WindowMessage::Quit => *control_flow = ControlFlow::Exit,
|
||||
},
|
||||
_ => {}
|
||||
pub fn run(mut self, event_loop: EventLoop<WindowMessage>) -> ! {
|
||||
event_loop.run(move |event, event_loop, control_flow| match event {
|
||||
Event::WindowEvent { window_id, event } => {
|
||||
if let Some(window) = self.windows.get_mut(&window_id) {
|
||||
match event {
|
||||
WindowEvent::Resized(_) => window.request_redraw(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(id) => {
|
||||
if let Some(window) = self.windows.get(&id) {
|
||||
let mut target = window.display.draw();
|
||||
target.clear_color(0.0, 0.0, 0.0, 1.0);
|
||||
target.finish().unwrap();
|
||||
}
|
||||
}
|
||||
Event::UserEvent(event) => match event {
|
||||
WindowMessage::OpenWindow { id } => {
|
||||
println!("Opening window {}", id);
|
||||
let window = Window::new(&event_loop).unwrap();
|
||||
let window_id = window.display.gl_window().window().id();
|
||||
self.windows.insert(window_id, window);
|
||||
self.ipc_to_window.insert(id, window_id);
|
||||
}
|
||||
WindowMessage::CloseWindow { id } => {
|
||||
if let Some(window_id) = self.ipc_to_window.remove(&id) {
|
||||
self.windows.remove(&window_id);
|
||||
}
|
||||
}
|
||||
WindowMessage::Quit => *control_flow = ControlFlow::Exit,
|
||||
},
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue