[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 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
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
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