[ref] Error handling outside of expect and unwrap

This commit is contained in:
2024-03-04 21:25:37 +05:30
parent df80ac5406
commit 3aa51389a3
3 changed files with 65 additions and 16 deletions

View File

@@ -14,6 +14,7 @@ use sdl2::render::{BlendMode, TextureAccess, 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;
use crate::util::EmulatorResult;
use crate::kb_map::get_key_index; use crate::kb_map::get_key_index;
use crate::sdl_graphics_adapter::SdlGraphicsAdapter; use crate::sdl_graphics_adapter::SdlGraphicsAdapter;
@@ -21,8 +22,9 @@ mod args;
mod device; mod device;
mod kb_map; mod kb_map;
mod sdl_graphics_adapter; mod sdl_graphics_adapter;
mod util;
fn main() { fn main() -> EmulatorResult<()> {
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap(); SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
log::info!("Started emulator"); log::info!("Started emulator");
@@ -36,9 +38,9 @@ fn main() {
let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || { let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || {
do_device_loop(timer, frame_buffer_for_device, termination_signal_sender_receiver); do_device_loop(timer, frame_buffer_for_device, termination_signal_sender_receiver);
}).expect("Failed to launch thread"); })?;
let (mut canvas, mut event_pump) = initiate_sdl(8f32); let (mut canvas, mut event_pump) = try_initiate_sdl(8f32)?;
let mut sdl_graphics_adapter = SdlGraphicsAdapter::new(); let mut sdl_graphics_adapter = SdlGraphicsAdapter::new();
@@ -70,8 +72,8 @@ fn main() {
// The rest of the game loop goes here... // The rest of the game loop goes here...
{ {
let lock = frame_buffer_for_display.lock().expect("Failed to get Display"); let lock = frame_buffer_for_display.lock()?;
sdl_graphics_adapter.draw_screen(lock, &mut canvas); sdl_graphics_adapter.draw_screen(lock, &mut canvas)?;
} }
canvas.present(); canvas.present();
@@ -81,6 +83,7 @@ fn main() {
compute_handle.join().unwrap(); compute_handle.join().unwrap();
Ok(())
} }
fn do_device_loop(mut timer: Timer, frame_buffer: Arc<Mutex<Box<[bool; 2048]>>>, receiver: Receiver<()>) { fn do_device_loop(mut timer: Timer, frame_buffer: Arc<Mutex<Box<[bool; 2048]>>>, receiver: Receiver<()>) {
@@ -118,7 +121,7 @@ fn load_rom() -> [u8; ROM_SIZE] {
rom_slice rom_slice
} }
fn initiate_sdl(draw_scale: f32) -> (WindowCanvas, EventPump) { fn try_initiate_sdl(draw_scale: f32) -> EmulatorResult<(WindowCanvas, EventPump)> {
let sdl_context = sdl2::init().unwrap(); let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap(); let video_subsystem = sdl_context.video().unwrap();
// let audio_subsystem = sdl_context.audio().unwrap(); // let audio_subsystem = sdl_context.audio().unwrap();
@@ -134,19 +137,18 @@ fn initiate_sdl(draw_scale: f32) -> (WindowCanvas, EventPump) {
let window = video_subsystem.window("porcel8", window_width, window_height) let window = video_subsystem.window("porcel8", window_width, window_height)
.position_centered() .position_centered()
.build() .build()?;
.unwrap(); let mut canvas = window.into_canvas().build()?;
let mut canvas = window.into_canvas().build().unwrap();
canvas.set_scale(draw_scale, draw_scale).expect("Setting scale"); canvas.set_scale(draw_scale, draw_scale)?;
canvas.set_blend_mode(BlendMode::None); canvas.set_blend_mode(BlendMode::None);
canvas.clear(); canvas.clear();
canvas.present(); canvas.present();
let event_pump = sdl_context.event_pump().unwrap(); let event_pump = sdl_context.event_pump()?;
(canvas, event_pump Ok((canvas, event_pump
// , audio_queue // , audio_queue
) ))
} }

View File

@@ -2,6 +2,7 @@ use std::sync::MutexGuard;
use sdl2::pixels::PixelFormatEnum; use sdl2::pixels::PixelFormatEnum;
use sdl2::render::{TextureAccess, WindowCanvas}; use sdl2::render::{TextureAccess, WindowCanvas};
use crate::device::Device; use crate::device::Device;
use crate::util::EmulatorResult;
#[derive(Debug)] #[derive(Debug)]
pub struct SdlGraphicsAdapter { pub struct SdlGraphicsAdapter {
@@ -17,20 +18,22 @@ impl SdlGraphicsAdapter {
rgb_frame_buffer rgb_frame_buffer
} }
} }
pub fn draw_screen(&mut self, frame_buffer: MutexGuard<Box<[bool; Device::FRAME_BUFFER_SIZE]>>, window_canvas: &mut WindowCanvas) { pub fn draw_screen(&mut self, frame_buffer: MutexGuard<Box<[bool; Device::FRAME_BUFFER_SIZE]>>, window_canvas: &mut WindowCanvas) ->EmulatorResult<()> {
for (i, pixel) in frame_buffer.iter().enumerate() { for (i, pixel) in frame_buffer.iter().enumerate() {
let col_component = if *pixel { 0xff } else { 0 }; let col_component = if *pixel { 0xff } else { 0 };
self.rgb_frame_buffer[3 * i] = col_component; self.rgb_frame_buffer[3 * i] = col_component;
self.rgb_frame_buffer[3 * i + 1] = col_component; self.rgb_frame_buffer[3 * i + 1] = col_component;
self.rgb_frame_buffer[3 * i + 2] = col_component; self.rgb_frame_buffer[3 * i + 2] = col_component;
} }
// drop the mutex as it is not required anymore
drop(frame_buffer); drop(frame_buffer);
let tex_creator = window_canvas.texture_creator(); let tex_creator = window_canvas.texture_creator();
let mut tex = tex_creator.create_texture(PixelFormatEnum::RGB24, TextureAccess::Streaming, Device::FRAME_BUFFER_WIDTH as u32, Device::FRAME_BUFFER_HEIGHT as u32).expect("Failed to create tex"); let mut tex = tex_creator.create_texture(PixelFormatEnum::RGB24, TextureAccess::Streaming, Device::FRAME_BUFFER_WIDTH as u32, Device::FRAME_BUFFER_HEIGHT as u32).expect("Failed to create tex");
tex.with_lock(None, |u, i| { tex.with_lock(None, |u, i| {
u.copy_from_slice(self.rgb_frame_buffer.as_slice()); u.copy_from_slice(self.rgb_frame_buffer.as_slice());
}).expect("Unwrap tex"); })?;
window_canvas.copy(&tex, None, None).expect("Failed to set texture"); window_canvas.copy(&tex, None, None)?;
Ok(())
} }
} }

44
src/util.rs Normal file
View File

@@ -0,0 +1,44 @@
use std::sync::PoisonError;
use sdl2::IntegerOrSdlError;
use sdl2::video::WindowBuildError;
pub type EmulatorResult<T> = Result<T, EmulatorError>;
#[derive(Clone, Debug)]
pub enum EmulatorError {
SdlError(String),
AllocationError,
IOError(String),
MutexInvalidState(String)
}
impl From<String> for EmulatorError {
fn from(value: String) -> Self {
Self::SdlError(value)
}
}
impl From<WindowBuildError> for EmulatorError {
fn from(value: WindowBuildError) -> Self {
Self::SdlError(value.to_string())
}
}
impl From<IntegerOrSdlError> for EmulatorError {
fn from(value: IntegerOrSdlError) -> Self {
match value {
IntegerOrSdlError::IntegerOverflows(x, y) => { Self::SdlError(format!("{} - {}", x, y)) }
IntegerOrSdlError::SdlError(str) => { Self::SdlError(str) }
}
}
}
impl From<std::io::Error> for EmulatorError{
fn from(value: std::io::Error) -> Self {
Self::IOError(value.to_string())
}
}
impl<T> From<PoisonError<T>> for EmulatorError{
fn from(value: PoisonError<T>) -> Self {
Self::MutexInvalidState(value.to_string())
}
}