Improve error handling & feedback.
Change default path to minetest.exe on Windows.
This commit is contained in:
parent
169c8ac7e3
commit
89d6f908c4
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
debug.txt
|
||||||
|
48
src/main.rs
48
src/main.rs
@ -3,15 +3,15 @@ extern crate regex;
|
|||||||
|
|
||||||
use mumble_link::*;
|
use mumble_link::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader, Read, Write};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
fn get_data(captures: ®ex::Captures) -> Result<([f32; 3], char, char), String> {
|
// Function to convert errors to error strings so we can return that as a result.
|
||||||
// Function to convert float parsing errors to error strings so we can return that as a result.
|
fn errstr<T>(e: T) -> String where T: ToString {
|
||||||
fn errstr(e: std::num::ParseFloatError) -> String {
|
|
||||||
e.to_string()
|
e.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_data(captures: ®ex::Captures) -> Result<([f32; 3], char, char), String> {
|
||||||
// Get all the named captures.
|
// Get all the named captures.
|
||||||
Ok(([captures["x"].parse().map_err(errstr)?, captures["y"].parse().map_err(errstr)?, captures["z"].parse().map_err(errstr)?,],
|
Ok(([captures["x"].parse().map_err(errstr)?, captures["y"].parse().map_err(errstr)?, captures["z"].parse().map_err(errstr)?,],
|
||||||
captures["subject"].chars().next().ok_or("unable to get vec subject")?,
|
captures["subject"].chars().next().ok_or("unable to get vec subject")?,
|
||||||
@ -19,12 +19,38 @@ fn get_data(captures: ®ex::Captures) -> Result<([f32; 3], char, char), String
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
match try_main() {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(err) => {
|
||||||
|
println!("Error: {}", err);
|
||||||
|
|
||||||
|
// print without a newline and flush to keep the cursor on the same line.
|
||||||
|
print!("Press ENTER to continue...");
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
|
||||||
|
// Read a single byte and discard.
|
||||||
|
let _ = std::io::stdin().read(&mut [0u8]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_main() -> Result<(), String> {
|
||||||
|
println!("Starting...");
|
||||||
|
|
||||||
// Hook into Mumble using the very handy crate somebody made.
|
// Hook into Mumble using the very handy crate somebody made.
|
||||||
let mut link = MumbleLink::new("Minetest", "Minetest positional audio using a mod and wrapper.").expect("Unable to link to Mumble. Is it running?");
|
let mut link = MumbleLink::new("Minetest", "Minetest positional audio using a mod and wrapper.")
|
||||||
|
.map_err(|e| { format!("Unable to connect to Mumble. Is it running? ({})", e) })?;
|
||||||
|
|
||||||
|
println!("Connected to Mumble successfully.");
|
||||||
|
|
||||||
// Default command to launch.
|
// Default command to launch.
|
||||||
let mut minetest_command = "/usr/bin/minetest".to_owned();
|
let mut minetest_command = if cfg!(windows) {
|
||||||
|
"C:\\Program Files\\minetest\\bin\\minetest.exe"
|
||||||
|
} else {
|
||||||
|
"/usr/bin/minetest"
|
||||||
|
}.to_owned();
|
||||||
|
|
||||||
// Look for an argument containing "minetest" to replace default command. (But make sure it isn't this exe because that just leads to crazy recursion...)
|
// Look for an argument containing "minetest" to replace default command. (But make sure it isn't this exe because that just leads to crazy recursion...)
|
||||||
for argument in std::env::args() {
|
for argument in std::env::args() {
|
||||||
@ -33,9 +59,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Launching Minetest at {}", minetest_command);
|
||||||
|
|
||||||
let mut child = Command::new(minetest_command)
|
let mut child = Command::new(minetest_command)
|
||||||
.stderr(Stdio::piped()) // We need the output to be piped. For some reason Minetest lua's print function goes to stderr...
|
.stderr(Stdio::piped()) // We need the output to be piped. For some reason Minetest lua's print function goes to stderr...
|
||||||
.spawn().unwrap(); // Spawn the process, panic if it fails.
|
.spawn().map_err(|e| { format!("Unable to start Minetest executable: {}", e) })?; // Spawn the process, return an error if it fails.
|
||||||
|
|
||||||
// This regex parses lines like "p l [1.0 1.0 1.0]".
|
// This regex parses lines like "p l [1.0 1.0 1.0]".
|
||||||
// the first letter (the subject) is either 'p' or 'c' denoting whether this is a player or camera vector.
|
// the first letter (the subject) is either 'p' or 'c' denoting whether this is a player or camera vector.
|
||||||
@ -51,7 +79,7 @@ fn main() {
|
|||||||
let mut camera = Position::default();
|
let mut camera = Position::default();
|
||||||
|
|
||||||
// Run as long as the child proccess is running.
|
// Run as long as the child proccess is running.
|
||||||
while child.try_wait().unwrap().is_none() {
|
while child.try_wait().map_err(errstr)?.is_none() {
|
||||||
// Get the output from the child process.
|
// Get the output from the child process.
|
||||||
if let Some(ref mut child_output) = child.stderr {
|
if let Some(ref mut child_output) = child.stderr {
|
||||||
// Using a BufReader allows us to go through all the lines in a loop.
|
// Using a BufReader allows us to go through all the lines in a loop.
|
||||||
@ -106,4 +134,6 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user