From d1df749e38ec176518998fe3add1b7dd9cf926a4 Mon Sep 17 00:00:00 2001 From: Marc Riera Date: Wed, 22 Feb 2023 23:09:04 +0100 Subject: [PATCH] Better error handling --- src/main.rs | 130 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 54 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0b5c877..35d4201 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ use std::fs::File; use std::io::Write; +use std::io::Result; +use std::process::Command; use std::time::{Duration, Instant}; use std::thread::sleep; + use evdev_rs::Device; use evdev_rs::InputEvent; use evdev_rs::ReadFlag; @@ -9,7 +12,7 @@ use evdev_rs::enums::EventCode; use evdev_rs::enums::EV_KEY; #[derive(Default)] -struct Controller { +struct ControllerState { power: u8, brake: u8, button_sl: bool, @@ -31,58 +34,67 @@ enum ControllerModel { TYPE2, } -fn main() { - let d1 = Device::new_from_path("/dev/input/event1").unwrap(); - let d2 = Device::new_from_path("/dev/input/event2").unwrap(); +fn main() -> Result<()> { + let d1 = Device::new_from_path("/dev/input/event1"); + let d2 = Device::new_from_path("/dev/input/event2"); - let mut controller: Controller = Default::default(); - let mut controller_model: ControllerModel = ControllerModel::NONE; + match (d1, d2) { + (Ok(d1), Ok(d2)) => { + let mut controller_state: ControllerState = Default::default(); + let mut controller_model: ControllerModel = ControllerModel::NONE; + + // Save current time and 5 seconds in the future to check for pressed buttons later + let start_time = Instant::now(); + let init_time = start_time + Duration::from_secs(5); + + // Turn on door light to indicate selection mode + set_lamp(true); + println!("Hold a button to select the controller model..."); - // Save current time and 5 seconds in the future to check for pressed buttons later - let start_time = Instant::now(); - let init_time = start_time + Duration::from_secs(5); + loop { + // Process events from both input devices + for device in [&d1, &d2] { + let ev = device.next_event(ReadFlag::NORMAL); + match ev { + Ok(ev) => read_input(ev.1, &mut controller_state), + Err(_e) => (), + } + } + + // If init time has passed, try to select model or quit + if controller_model == ControllerModel::NONE && Instant::now() >= init_time { + if controller_state.button_right { + controller_model = ControllerModel::DGOC44U; + println!("Selected controller DGOC44-U, starting gadget..."); + } + else if controller_state.button_left { + controller_model = ControllerModel::TYPE2; + println!("Selected controller TCPP-20009, starting gadget..."); + } + else + { + // Turn off door light and quit + set_lamp(false); + println!("No controller selected, exiting..."); + break; + } + // Turn off door light and vibrate to end selection mode + set_lamp(false); + set_rumble(true); + sleep(Duration::from_millis(500)); + set_rumble(false); - // Turn on door light to indicate selection mode - set_door(true); - println!("Hold a button to select the controller model..."); - - loop { - // Process events from both input devices - for device in [&d1, &d2] { - let ev = device.next_event(ReadFlag::NORMAL).map(|val| val.1); - match ev { - Ok(ev) => read_input(ev, &mut controller), - Err(_e) => (), + // Stop main game + stop_game(); + } } - } - - // If init time has passed, try to select model or quit - if controller_model == ControllerModel::NONE && Instant::now() >= init_time { - if controller.button_right { - controller_model = ControllerModel::DGOC44U; - println!("Selected controller DGOC44-U, starting gadget..."); - } - else if controller.button_left { - controller_model = ControllerModel::TYPE2; - println!("Selected controller TCPP-20009, starting gadget..."); - } - else - { - // Turn off door light and quit - set_door(false); - println!("No controller selected, exiting..."); - break; - } - // Turn off door light and vibrate to end selection mode - set_door(false); - set_rumble(true); - sleep(Duration::from_millis(500)); - set_rumble(false); - } + }, + _ => println!("ERROR: Could not read input devices! Stopping..."), } + Ok(()) } -fn read_input(event: InputEvent, controller: &mut Controller) { +fn read_input(event: InputEvent, controller: &mut ControllerState) { // Save input status to object for easier processing match event.event_code{ EventCode::EV_KEY(EV_KEY::KEY_0)=>if event.value == 1 {controller.power = 0}, @@ -115,14 +127,24 @@ fn read_input(event: InputEvent, controller: &mut Controller) { } } -fn set_door(status: bool) -> std::io::Result<()> { - let mut out = File::create("/sys/class/leds/led2/brightness")?; - out.write(if status {b"1"} else {b"0"})?; - Ok(()) +fn set_lamp(status: bool) { + if let Ok(mut out) = File::create("/sys/class/leds/led2/brightness") { + out.write(if status {b"1"} else {b"0"}).ok(); + } + else { + println!("WARNING: Could not set door lamp status!") + } } -fn set_rumble(status: bool) -> std::io::Result<()> { - let mut out = File::create("/sys/class/leds/led1/brightness")?; - out.write(if status {b"1"} else {b"0"})?; - Ok(()) +fn set_rumble(status: bool) { + if let Ok(mut out) = File::create("/sys/class/leds/led1/brightness") { + out.write(if status {b"1"} else {b"0"}).ok(); + } + else { + println!("WARNING: Could not set rumble motor status!") + } } + +fn stop_game() { + Command::new("/etc/init.d/S99dgtype3").arg("stop").output().ok(); +} \ No newline at end of file