[tim] Cleanup on timer aisle
This commit is contained in:
@@ -1,64 +1,71 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::sync::mpsc::SendError;
|
||||||
use std::thread::{JoinHandle, sleep};
|
use std::thread::{JoinHandle, sleep};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use crate::util::EmulatorResult;
|
||||||
|
|
||||||
pub struct Timer{
|
pub struct Timer {
|
||||||
timer_left: Arc<Mutex<u16>>,
|
timer_left: Arc<Mutex<u16>>,
|
||||||
join_handle: Option<(JoinHandle<()>,std::sync::mpsc::Sender<()>)>
|
join_handle: Option<(JoinHandle<()>, std::sync::mpsc::Sender<()>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timer{
|
impl Timer {
|
||||||
pub fn new()->Timer{
|
pub fn new() -> Timer {
|
||||||
Timer{timer_left:Arc::new(Mutex::default()),join_handle:None}
|
Timer { timer_left: Arc::new(Mutex::default()), join_handle: None }
|
||||||
}
|
}
|
||||||
pub fn start(&mut self){
|
pub fn start(&mut self) {
|
||||||
let timer_left_ref = self.timer_left.clone();
|
let timer_left_ref = self.timer_left.clone();
|
||||||
let (sender,receiver) = std::sync::mpsc::channel();
|
let (sender, receiver) = std::sync::mpsc::channel();
|
||||||
let res = std::thread::spawn(move ||{
|
let res = std::thread::spawn(move || {
|
||||||
loop{
|
loop {
|
||||||
let val = receiver.try_recv();
|
let val = receiver.try_recv();
|
||||||
if let Ok(()) = val{
|
if let Ok(()) = val {
|
||||||
break;
|
break;
|
||||||
}else if let Err(std::sync::mpsc::TryRecvError::Disconnected) = val{
|
} else if let Err(std::sync::mpsc::TryRecvError::Disconnected) = val {
|
||||||
panic!("Disconnected");
|
panic!("Disconnected");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut timer_lock = timer_left_ref.lock().expect("Failed to lock");
|
let mut timer_lock = timer_left_ref.lock().expect("Failed to lock");
|
||||||
if *timer_lock >0 {
|
if *timer_lock > 0 {
|
||||||
*timer_lock -= 1;
|
*timer_lock -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sleep(Duration::from_secs_f32(1f32/60f32));
|
sleep(Duration::from_secs_f32(1f32 / 60f32));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
self.join_handle = Some((res,sender));
|
self.join_handle = Some((res, sender));
|
||||||
}
|
}
|
||||||
/// Set a timer down tick from `val`
|
/// Set a timer down tick from `val`
|
||||||
pub fn set_timer(& self,val:u16){
|
pub fn try_set_timer(&self, val: u16) -> EmulatorResult<()> {
|
||||||
let mut timer_val = self.timer_left.lock().expect("Failed to get mutex");
|
let mut timer_val = self.timer_left.lock()?;
|
||||||
*timer_val = val;
|
*timer_val = val;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_value(&self)->u16{
|
pub fn poll_value(&self) -> EmulatorResult<u16> {
|
||||||
let res = self.timer_left.lock().expect("Failed to lock?");
|
let res = self.timer_left.lock()?;
|
||||||
res.clone()
|
Ok(res.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(self){
|
pub fn stop(self) {
|
||||||
if let Some((u,x)) = self.join_handle{
|
if let Some((u, x)) = self.join_handle {
|
||||||
x.send(()).expect("Failed to send signal to close thread");
|
|
||||||
u.join().expect("Failed to close thread");
|
u.join().expect("Failed to close thread");
|
||||||
}else{
|
} else {
|
||||||
log::warn!("Nothing present!");
|
log::warn!("Nothing present!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn send_stop_signal(&mut self){
|
pub fn send_stop_signal(&mut self) {
|
||||||
if let Some((_,x)) = &self.join_handle{
|
if let Some((_, x)) = &self.join_handle {
|
||||||
x.send(()).expect("Failed to send signal to close thread");
|
match x.send(()) {
|
||||||
}else{
|
Ok(_) => {
|
||||||
|
log::trace!("Sent stop Signal")
|
||||||
|
}
|
||||||
|
Err(SendError(_)) => {
|
||||||
|
log::info!("Thread already stopped!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
log::warn!("Nothing present!");
|
log::warn!("Nothing present!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
11
src/main.rs
11
src/main.rs
@@ -1,6 +1,6 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -9,8 +9,10 @@ use sdl2::audio::{AudioQueue, AudioSpecDesired};
|
|||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::EventPump;
|
use sdl2::EventPump;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::pixels::{Color, PixelFormatEnum};
|
use sdl2::pixels::Color;
|
||||||
use sdl2::render::{BlendMode, TextureAccess, WindowCanvas};
|
use sdl2::render::BlendMode;
|
||||||
|
|
||||||
|
use sdl2::render::WindowCanvas;
|
||||||
use simple_logger::SimpleLogger;
|
use simple_logger::SimpleLogger;
|
||||||
use device::timer::Timer;
|
use device::timer::Timer;
|
||||||
use crate::device::Device;
|
use crate::device::Device;
|
||||||
@@ -81,8 +83,7 @@ fn main() -> EmulatorResult<()> {
|
|||||||
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60 ));
|
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compute_handle.join().expect("Failed to close compute thread");
|
||||||
compute_handle.join().unwrap();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ use sdl2::video::WindowBuildError;
|
|||||||
|
|
||||||
pub type EmulatorResult<T> = Result<T, EmulatorError>;
|
pub type EmulatorResult<T> = Result<T, EmulatorError>;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum EmulatorError {
|
pub enum EmulatorError {
|
||||||
SdlError(String),
|
SdlError(String),
|
||||||
@@ -41,4 +42,4 @@ impl<T> From<PoisonError<T>> for EmulatorError{
|
|||||||
fn from(value: PoisonError<T>) -> Self {
|
fn from(value: PoisonError<T>) -> Self {
|
||||||
Self::MutexInvalidState(value.to_string())
|
Self::MutexInvalidState(value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user