[ref] Error handling outside of expect and unwrap
This commit is contained in:
28
src/main.rs
28
src/main.rs
@@ -14,6 +14,7 @@ use sdl2::render::{BlendMode, TextureAccess, WindowCanvas};
|
||||
use simple_logger::SimpleLogger;
|
||||
use device::timer::Timer;
|
||||
use crate::device::Device;
|
||||
use crate::util::EmulatorResult;
|
||||
use crate::kb_map::get_key_index;
|
||||
use crate::sdl_graphics_adapter::SdlGraphicsAdapter;
|
||||
|
||||
@@ -21,8 +22,9 @@ mod args;
|
||||
mod device;
|
||||
mod kb_map;
|
||||
mod sdl_graphics_adapter;
|
||||
mod util;
|
||||
|
||||
fn main() {
|
||||
fn main() -> EmulatorResult<()> {
|
||||
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
|
||||
log::info!("Started emulator");
|
||||
|
||||
@@ -36,9 +38,9 @@ fn main() {
|
||||
|
||||
let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || {
|
||||
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();
|
||||
|
||||
@@ -70,8 +72,8 @@ fn main() {
|
||||
|
||||
// The rest of the game loop goes here...
|
||||
{
|
||||
let lock = frame_buffer_for_display.lock().expect("Failed to get Display");
|
||||
sdl_graphics_adapter.draw_screen(lock, &mut canvas);
|
||||
let lock = frame_buffer_for_display.lock()?;
|
||||
sdl_graphics_adapter.draw_screen(lock, &mut canvas)?;
|
||||
}
|
||||
canvas.present();
|
||||
|
||||
@@ -81,6 +83,7 @@ fn main() {
|
||||
|
||||
|
||||
compute_handle.join().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 video_subsystem = sdl_context.video().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)
|
||||
.position_centered()
|
||||
.build()
|
||||
.unwrap();
|
||||
let mut canvas = window.into_canvas().build().unwrap();
|
||||
.build()?;
|
||||
let mut canvas = window.into_canvas().build()?;
|
||||
|
||||
canvas.set_scale(draw_scale, draw_scale).expect("Setting scale");
|
||||
canvas.set_scale(draw_scale, draw_scale)?;
|
||||
|
||||
canvas.set_blend_mode(BlendMode::None);
|
||||
canvas.clear();
|
||||
canvas.present();
|
||||
let event_pump = sdl_context.event_pump().unwrap();
|
||||
(canvas, event_pump
|
||||
let event_pump = sdl_context.event_pump()?;
|
||||
Ok((canvas, event_pump
|
||||
// , audio_queue
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
|
@@ -2,6 +2,7 @@ use std::sync::MutexGuard;
|
||||
use sdl2::pixels::PixelFormatEnum;
|
||||
use sdl2::render::{TextureAccess, WindowCanvas};
|
||||
use crate::device::Device;
|
||||
use crate::util::EmulatorResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SdlGraphicsAdapter {
|
||||
@@ -17,20 +18,22 @@ impl SdlGraphicsAdapter {
|
||||
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() {
|
||||
let col_component = if *pixel { 0xff } else { 0 };
|
||||
self.rgb_frame_buffer[3 * i] = col_component;
|
||||
self.rgb_frame_buffer[3 * i + 1] = col_component;
|
||||
self.rgb_frame_buffer[3 * i + 2] = col_component;
|
||||
}
|
||||
// drop the mutex as it is not required anymore
|
||||
drop(frame_buffer);
|
||||
|
||||
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");
|
||||
tex.with_lock(None, |u, i| {
|
||||
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
44
src/util.rs
Normal 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())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user