add error handling

This commit is contained in:
Robert 2023-02-08 00:44:14 +01:00
parent a6bc9e1105
commit caeb083a3d
5 changed files with 73 additions and 23 deletions

View file

@ -10,4 +10,4 @@ vulkano = "0.31.0"
glfw = { version = "0.50.0", features = ["vulkan"] } glfw = { version = "0.50.0", features = ["vulkan"] }
[profile.dev] [profile.dev]
opt-level = 1 # opt-level = 1

View file

@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::window::Window; use crate::{window::Window, error::ApplicationError};
fn key_callback_func(window: &mut glfw::Window, key: glfw::Key, _: glfw::Scancode, action: glfw::Action, _: glfw::Modifiers) { fn key_callback_func(window: &mut glfw::Window, key: glfw::Key, _: glfw::Scancode, action: glfw::Action, _: glfw::Modifiers) {
if key == glfw::Key::Escape && action == glfw::Action::Press { if key == glfw::Key::Escape && action == glfw::Action::Press {
@ -16,10 +16,10 @@ pub struct Application {
} }
impl Application { impl Application {
pub fn new() -> Result<Application, &'static str> { pub fn new() -> Result<Application, ApplicationError> {
let mut glfw = match glfw::init(glfw::FAIL_ON_ERRORS) { let mut glfw = match glfw::init(glfw::FAIL_ON_ERRORS) {
Ok(instance) => instance, Ok(instance) => instance,
Err(_) => return Err("Failed to initialize GLFW") Err(_) => return Err(ApplicationError::new("GLFW", "Failed to initialize GLFW"))
}; };
let mut window = Window::new(&mut glfw, 800, 800, "Vulkan Test")?; let mut window = Window::new(&mut glfw, 800, 800, "Vulkan Test")?;
@ -35,29 +35,27 @@ impl Application {
}) })
} }
fn init_vulkan(glfw: &glfw::Glfw) -> Result<Arc<vulkano::instance::Instance>, &'static str> { fn init_vulkan(glfw: &glfw::Glfw) -> Result<Arc<vulkano::instance::Instance>, ApplicationError> {
let mut create_info = vulkano::instance::InstanceCreateInfo::application_from_cargo_toml(); let mut create_info = vulkano::instance::InstanceCreateInfo::application_from_cargo_toml();
create_info.engine_name = Some("No engine".into()); create_info.engine_name = Some("No engine".into());
create_info.engine_version = vulkano::Version::V1_0; create_info.engine_version = vulkano::Version::V1_0;
create_info.max_api_version = Some(vulkano::Version::V1_0); create_info.max_api_version = Some(vulkano::Version::V1_0);
if let Some(extensions) = glfw.get_required_instance_extensions() { let required_extensions = glfw.get_required_instance_extensions().ok_or(
create_info.enabled_extensions = vulkano::instance::InstanceExtensions::from_iter(extensions.iter().map(|name| name.as_str())); ApplicationError::new("GLFW", "Failed to get required GLFW extensions")
} else { )?;
return Err("Failed to fetch GLFW's required instance extensions");
}
if let Ok(library) = vulkano::VulkanLibrary::new() { create_info.enabled_extensions = vulkano::instance::InstanceExtensions::from_iter(
return match vulkano::instance::Instance::new(library, create_info) { required_extensions.iter().map(|ext| ext.as_str())
Ok(instance) => Ok(instance), );
Err(_) => Err("Failed to create Vulkan instance")
};
}
return Err("Failed to create Vulkano library"); let library = vulkano::library::VulkanLibrary::new()?;
let instance = vulkano::instance::Instance::new(library, create_info)?;
Ok(instance)
} }
pub fn run(&mut self) -> Result<(), &'static str> { pub fn run(&mut self) -> Result<(), ApplicationError> {
while !self.window.should_close() { while !self.window.should_close() {
self.glfw.poll_events(); self.glfw.poll_events();
self.window.handle_events(); self.window.handle_events();

50
src/error.rs Normal file
View file

@ -0,0 +1,50 @@
use std::fmt::Display;
use vulkano::{LoadingError, instance::{self, InstanceCreationError, Instance, InstanceCreateInfo}};
#[derive(Debug)]
pub struct ApplicationError {
what: String,
which: String
}
impl ApplicationError {
pub fn new(which: &str, what: &str) -> ApplicationError {
ApplicationError { what: what.into(), which: which.into() }
}
}
impl Display for ApplicationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "[{}] {}", self.which, self.what)
}
}
impl From<LoadingError> for ApplicationError {
fn from(value: LoadingError) -> Self {
ApplicationError {
which: "Loading Error".into(),
what: match value {
LoadingError::LibraryLoadFailure(error) => error.to_string(),
LoadingError::OomError(error) => error.to_string()
}
}
}
}
impl From<InstanceCreationError> for ApplicationError {
fn from(value: InstanceCreationError) -> Self {
ApplicationError {
what: "Instance Creation Error".into(),
which: match value {
InstanceCreationError::ExtensionNotPresent => "Extension not present".into(),
InstanceCreationError::ExtensionRestrictionNotMet(error) => error.to_string(),
InstanceCreationError::IncompatibleDriver => "Incompatible driver".into(),
InstanceCreationError::InitializationFailed => "Initialization failed".into(),
InstanceCreationError::LayerNotPresent => "Layer not present".into(),
InstanceCreationError::OomError(error) => error.to_string(),
InstanceCreationError::RequirementNotMet { required_for, requires_one_of } => format!("{} requires one of {}", required_for, requires_one_of)
}
}
}
}

View file

@ -2,6 +2,7 @@ use application::Application;
mod application; mod application;
mod window; mod window;
mod error;
fn main() { fn main() {
let mut app = Application::new().unwrap(); let mut app = Application::new().unwrap();

View file

@ -1,5 +1,7 @@
use std::{sync::mpsc::Receiver, ops::Deref}; use std::{sync::mpsc::Receiver, ops::Deref};
use crate::{error::ApplicationError, application::Application};
type KeyCallbackFunc = fn(&mut glfw::Window, glfw::Key, glfw::Scancode, glfw::Action, glfw::Modifiers); type KeyCallbackFunc = fn(&mut glfw::Window, glfw::Key, glfw::Scancode, glfw::Action, glfw::Modifiers);
pub struct Window { pub struct Window {
@ -10,14 +12,13 @@ pub struct Window {
} }
impl Window { impl Window {
pub fn new(glfw: &mut glfw::Glfw, width: u32, height: u32, title: &str) -> Result<Window, &'static str> { pub fn new(glfw: &mut glfw::Glfw, width: u32, height: u32, title: &str) -> Result<Window, ApplicationError> {
glfw.window_hint(glfw::WindowHint::Resizable(false)); glfw.window_hint(glfw::WindowHint::Resizable(false));
glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::NoApi)); glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::NoApi));
let (mut window, events) = match glfw.create_window(width, height, title, glfw::WindowMode::Windowed) { let (mut window, events) =
Some(val) => val, glfw.create_window(width, height, title, glfw::WindowMode::Windowed)
None => return Err("Failed to create window and event receiver") .ok_or(ApplicationError::new("Window", "Failed to create window and event receiver"))?;
};
window.set_key_polling(true); window.set_key_polling(true);