handle window crashes, various fixes
add reversi, fixes for audio player and terminal
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::vec::Vec;
|
||||
use std::process::{ Command, Child, Stdio };
|
||||
use std::io::{ BufReader, BufRead, Read, Write };
|
||||
use std::io::{ BufReader, BufRead, Write };
|
||||
use std::cell::RefCell;
|
||||
|
||||
use ron;
|
||||
@@ -14,66 +14,91 @@ pub struct ProxyWindowLike {
|
||||
process: RefCell<Child>,
|
||||
}
|
||||
|
||||
//try to handle panics of child processes so the entire wm doesn't crash
|
||||
//we can "guarantee" that the ron::to_string(...).unwrap() calls will never panic
|
||||
impl WindowLike for ProxyWindowLike {
|
||||
fn handle_message(&mut self, message: WindowMessage) -> WindowMessageResponse {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all(("handle_message ".to_string() + &ron::to_string(&message).unwrap() + "\n").as_bytes());
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all(("handle_message ".to_string() + &ron::to_string(&message).unwrap() + "\n").as_bytes());
|
||||
}
|
||||
let output = self.read_line();
|
||||
ron::from_str(&output).unwrap()
|
||||
ron::from_str(&output).unwrap_or(WindowMessageResponse::JustRerender)
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all(("draw ".to_string() + &ron::to_string(&theme_info).unwrap() + "\n").as_bytes());
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all(("draw ".to_string() + &ron::to_string(&theme_info).unwrap() + "\n").as_bytes());
|
||||
}
|
||||
let output = self.read_line();
|
||||
ron::from_str(&output).unwrap()
|
||||
ron::from_str(&output).unwrap_or(Vec::new())
|
||||
}
|
||||
|
||||
//properties
|
||||
fn title(&self) -> String {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all("title\n".as_bytes());
|
||||
self.read_line()
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all("title\n".as_bytes());
|
||||
}
|
||||
self.read_line().chars().filter(|c| *c != '\n').collect()
|
||||
}
|
||||
|
||||
fn resizable(&self) -> bool {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all("resizable\n".to_string().as_bytes());
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all("resizable\n".to_string().as_bytes());
|
||||
}
|
||||
let output = self.read_line();
|
||||
ron::from_str(&output).unwrap()
|
||||
ron::from_str(&output).unwrap_or(false)
|
||||
}
|
||||
|
||||
fn subtype(&self) -> WindowLikeType {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all("subtype\n".to_string().as_bytes());
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all("subtype\n".to_string().as_bytes());
|
||||
}
|
||||
let output = self.read_line();
|
||||
ron::from_str(&output).unwrap()
|
||||
ron::from_str(&output).unwrap_or(WindowLikeType::Window)
|
||||
}
|
||||
|
||||
fn ideal_dimensions(&self, dimensions: Dimensions) -> Dimensions {
|
||||
self.process.borrow_mut().stdin.as_mut().unwrap().write_all(("ideal_dimensions".to_string() + &ron::to_string(&dimensions).unwrap() + "\n").as_bytes());
|
||||
if let Some(stdin) = self.process.borrow_mut().stdin.as_mut() {
|
||||
let _ = stdin.write_all(("ideal_dimensions ".to_string() + &ron::to_string(&dimensions).unwrap() + "\n").as_bytes());
|
||||
}
|
||||
let output = self.read_line();
|
||||
ron::from_str(&output).unwrap()
|
||||
ron::from_str(&output).unwrap_or([420, 420])
|
||||
}
|
||||
}
|
||||
|
||||
//kill process when this window like dropped
|
||||
impl Drop for ProxyWindowLike {
|
||||
fn drop(&mut self) {
|
||||
self.process.borrow_mut().kill();
|
||||
let _ = self.process.borrow_mut().kill();
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxyWindowLike {
|
||||
pub fn new(file: &str) -> Self {
|
||||
pub fn new(command: &mut Command) -> Self {
|
||||
ProxyWindowLike {
|
||||
//--quiet
|
||||
process: RefCell::new(Command::new("cargo").arg("run").arg("--quiet").arg("--release").arg("--bin").arg(file).stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()).spawn().unwrap()),
|
||||
process: RefCell::new(command.stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()).spawn().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_rust(file: &str) -> Self {
|
||||
ProxyWindowLike::new(Command::new("cargo").arg("run").arg("--quiet").arg("--release").arg("--bin").arg(file).stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()))
|
||||
}
|
||||
|
||||
//return empty string if error, do not propogate Err becuase that's messy
|
||||
//or maybe return "panicked"?
|
||||
fn read_line(&self) -> String {
|
||||
let mut output = String::new();
|
||||
let mut buffer = self.process.borrow_mut();
|
||||
let buffer = buffer.stdout.as_mut().unwrap();
|
||||
let mut reader = BufReader::new(buffer);
|
||||
reader.read_line(&mut output).unwrap();
|
||||
output
|
||||
if let Some(buffer) = buffer.stdout.as_mut() {
|
||||
let mut output = String::new();
|
||||
let mut reader = BufReader::new(buffer);
|
||||
if let Ok(_) = reader.read_line(&mut output) {
|
||||
output
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user