Skip to content
This repository has been archived by the owner on Apr 18, 2022. It is now read-only.

[wip] Implement error handling using error-chain #332

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions amethyst_renderer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ rayon = "0.8"
serde = "1.0"
serde_derive = "1.0"
winit = "0.7"
error-chain = "0.10"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There already is 0.11 btw

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ty


gfx_device_gl = { version = "0.14", optional = true }
gfx_window_glutin = { version = "0.17", optional = true }
Expand Down
21 changes: 11 additions & 10 deletions amethyst_renderer/examples/material.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Launches a new renderer window.

#[macro_use] extern crate error_chain;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd, I've been writing mine as

#[macro_use]
extern crate error_chain;

Is it documented anywhere what style these should be? I wasn't able to find documentation for this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I'm not requesting this be changed I just want to know if I've been doing mine wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I typically have been doing it your way, but there are some merits to the one liner.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm completely indifferent - I'll change to the amethyst standard :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you do cargo fmt?

extern crate amethyst_renderer as renderer;
extern crate cgmath;
extern crate genmesh;
Expand All @@ -11,27 +12,25 @@ use genmesh::{MapToVertices, Triangulate, Vertices};
use genmesh::generators::SphereUV;
use renderer::prelude::*;
use renderer::vertex::PosNormTangTex;
use renderer::Result;

fn main() {
fn run() -> Result<()> {
use std::time::{Duration, Instant};
use winit::{Event, EventsLoop, WindowEvent};

let mut events = EventsLoop::new();
let mut renderer = Renderer::new(&events).expect("Renderer create");
let mut renderer = Renderer::new(&events)?;
let pipe = renderer
.create_pipe(
Pipeline::build().with_stage(
Stage::with_backbuffer()
.clear_target([0.0, 0.0, 0.0, 1.0], 2.0)
.with_model_pass(pass::DrawShaded::<PosNormTangTex>::new()),
),
)
.expect("Pipeline create");
)?;

let verts = gen_sphere(64, 64);
let mesh = renderer.create_mesh(Mesh::build(&verts)).expect(
"Mesh create",
);
let mesh = renderer.create_mesh(Mesh::build(&verts))?;

let mut scene = Scene::default();
let alb = Texture::from_color_val([1.0; 4]);
Expand All @@ -52,8 +51,7 @@ fn main() {
.with_albedo(alb.clone())
.with_roughness(rog)
.with_metallic(met),
)
.expect("Material create");
)?;
let model = Model {
mesh: mesh.clone(),
material: mtl,
Expand Down Expand Up @@ -103,11 +101,14 @@ fn main() {
_ => (),
});

renderer.draw(&scene, &pipe, delta);
renderer.draw(&scene, &pipe, delta)?;
delta = Instant::now() - start;
}
Ok(())
}

quick_main!(run);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Examples should, if possible, avoid macros IMO.

Copy link
Contributor

@Emilgardis Emilgardis Sep 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick_main! could easily be replaced with how it is recommended to be done: link

fn main() {
    if let Err(ref e) = run() {
        use std::io::Write;
        let stderr = &mut ::std::io::stderr();
        let errmsg = "Error writing to stderr";

        writeln!(stderr, "error: {}", e).expect(errmsg);

        for e in e.iter().skip(1) {
            writeln!(stderr, "caused by: {}", e).expect(errmsg);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
        }

        ::std::process::exit(1);
    }
}


fn gen_sphere(u: usize, v: usize) -> Vec<PosNormTangTex> {
SphereUV::new(u, v)
.vertex(|(x, y, z)| {
Expand Down
21 changes: 11 additions & 10 deletions amethyst_renderer/examples/sphere.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Launches a new renderer window.

#[macro_use] extern crate error_chain;
extern crate amethyst_renderer as renderer;
extern crate cgmath;
extern crate genmesh;
Expand All @@ -11,32 +12,29 @@ use genmesh::{MapToVertices, Triangulate, Vertices};
use genmesh::generators::SphereUV;
use renderer::prelude::*;
use renderer::vertex::PosNormTex;
use renderer::Result;

fn main() {
fn run() -> Result<()> {
use std::time::{Duration, Instant};
use winit::{Event, EventsLoop, WindowEvent};

let mut events = EventsLoop::new();
let mut renderer = Renderer::new(&events).expect("Renderer create");
let mut renderer = Renderer::new(&events)?;
let pipe = renderer
.create_pipe(
Pipeline::build().with_stage(
Stage::with_backbuffer()
.clear_target([0.00196, 0.23726, 0.21765, 1.0], 1.0)
.with_model_pass(pass::DrawFlat::<PosNormTex>::new()),
),
)
.expect("Pipeline create");
)?;

let verts = gen_sphere(32, 32);
let mesh = renderer.create_mesh(Mesh::build(&verts)).expect(
"Mesh create",
);
let mesh = renderer.create_mesh(Mesh::build(&verts))?;

let tex = Texture::from_color_val([0.88235, 0.09412, 0.21569, 1.0]);
let mtl = renderer
.create_material(MaterialBuilder::new().with_albedo(tex))
.expect("Material create");
.create_material(MaterialBuilder::new().with_albedo(tex))?;
let model = Model {
mesh: mesh,
material: mtl,
Expand Down Expand Up @@ -70,11 +68,14 @@ fn main() {
_ => (),
});

renderer.draw(&scene, &pipe, delta);
renderer.draw(&scene, &pipe, delta)?;
delta = Instant::now() - start;
}
Ok(())
}

quick_main!(run);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future we should replace this with main again: rust-lang/rust#43301


fn gen_sphere(u: usize, v: usize) -> Vec<PosNormTex> {
SphereUV::new(u, v)
.vertex(|(x, y, z)| {
Expand Down
13 changes: 9 additions & 4 deletions amethyst_renderer/examples/window.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
//! Launches a new renderer window.

#[macro_use] extern crate error_chain;
extern crate amethyst_renderer as renderer;
extern crate winit;

use std::time::{Duration, Instant};

use winit::{Event, EventsLoop, WindowEvent};
use renderer::prelude::*;
use renderer::Result;

fn main() {
fn run() -> Result<()> {
let mut events = EventsLoop::new();
let mut renderer = Renderer::new(&events).unwrap();
let pipe = renderer.create_pipe(Pipeline::forward::<PosTex>()).unwrap();
let mut renderer = Renderer::new(&events)?;
let pipe = renderer.create_pipe(Pipeline::forward::<PosTex>())?;
let scene = Scene::default();

let mut delta = Duration::from_secs(0);
Expand All @@ -30,7 +32,10 @@ fn main() {
_ => (),
});

renderer.draw(&scene, &pipe, delta);
renderer.draw(&scene, &pipe, delta)?;
delta = Instant::now() - start;
}
Ok(())
}

quick_main!(run);
168 changes: 56 additions & 112 deletions amethyst_renderer/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,70 @@
//! Renderer error types.

use std::error::Error as StdError;
use std::fmt::{Display, Formatter};
use std::fmt::Result as FmtResult;
use std::result::Result as StdResult;

use gfx;
use gfx_core;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not recommended error_chain usage. It is advised to use paths from root, i.e ::gfx_core::*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if it works I don't see any problems.

use glutin;

/// Renderer result type.
pub type Result<T> = StdResult<T, Error>;
error_chain! {

/// Common renderer error type.
#[derive(Debug)]
pub enum Error {
/// Failed to create a buffer.
BufferCreation(gfx::buffer::CreationError),
/// A render target with the given name does not exist.
NoSuchTarget(String),
/// Failed to initialize a render pass.
PassInit(gfx::PipelineStateError<String>),
/// Failed to create a pipeline state object (PSO).
PipelineCreation(gfx_core::pso::CreationError),
/// Failed to create thread pool.
PoolCreation(String),
/// Failed to create and link a shader program.
ProgramCreation(gfx::shade::ProgramError),
/// Failed to create a resource view.
ResViewCreation(gfx::ResourceViewError),
/// Failed to create a render target.
TargetCreation(gfx::CombinedError),
/// Failed to create a texture resource.
TextureCreation(gfx::texture::CreationError),
/// The window handle associated with the renderer has been destroyed.
WindowDestroyed,
}
foreign_links {

impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::BufferCreation(_) => "Failed to create buffer!",
Error::NoSuchTarget(_) => "Target with this name does not exist!",
Error::PassInit(_) => "Failed to initialize render pass!",
Error::PipelineCreation(_) => "Failed to create PSO!",
Error::PoolCreation(_) => "Failed to create thread pool!",
Error::ProgramCreation(_) => "Failed to create shader program!",
Error::ResViewCreation(_) => "Failed to create resource view!",
Error::TargetCreation(_) => "Failed to create render target!",
Error::TextureCreation(_) => "Failed to create texture!",
Error::WindowDestroyed => "Window has been destroyed!",
}
BufferCreation(gfx::buffer::CreationError)
#[doc="Error occured during buffer creation"];
PipelineState(gfx::PipelineStateError<String>)
#[doc="Error occured in pipeline state"];
PsoCreation(gfx_core::pso::CreationError)
#[doc="Error occured during pipeline state object creation"];
ShaderProgram(gfx::shade::ProgramError)
#[doc="Error occured during shader compilation"];
ResourceView(gfx::ResourceViewError)
#[doc="Error occured in resource view"];
GfxCombined(gfx::CombinedError)
#[doc="Gfx combined error type"];
TextureCreation(gfx::texture::CreationError)
#[doc="Error occured during texture creation"];
GlutinContext(glutin::ContextError) // todo #[cfg(glutin)] only
#[doc="(gl specific) Error occured in gl context"];
}

fn cause(&self) -> Option<&StdError> {
match *self {
Error::BufferCreation(ref e) => Some(e),
Error::PassInit(ref e) => Some(e),
Error::PipelineCreation(ref e) => Some(e),
Error::ProgramCreation(ref e) => Some(e),
Error::ResViewCreation(ref e) => Some(e),
Error::TargetCreation(ref e) => Some(e),
Error::TextureCreation(ref e) => Some(e),
_ => None,
errors {
/// A render target with the given name does not exist.
NoSuchTarget(e: String) {
description("Target with this name does not exist!")
display("Nonexistent target: {}", e)
}
}
}

impl Display for Error {
fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
match *self {
Error::BufferCreation(ref e) => write!(fmt, "Buffer creation failed: {}", e),
Error::NoSuchTarget(ref e) => write!(fmt, "Nonexistent target: {}", e),
Error::PassInit(ref e) => write!(fmt, "Pass initialization failed: {}", e),
Error::PipelineCreation(ref e) => write!(fmt, "PSO creation failed: {}", e),
Error::PoolCreation(ref e) => write!(fmt, "Thread pool creation failed: {}", e),
Error::ProgramCreation(ref e) => write!(fmt, "Program compilation failed: {}", e),
Error::ResViewCreation(ref e) => write!(fmt, "Resource view creation failed: {}", e),
Error::TargetCreation(ref e) => write!(fmt, "Target creation failed: {}", e),
Error::TextureCreation(ref e) => write!(fmt, "Texture creation failed: {}", e),
Error::WindowDestroyed => write!(fmt, "Window has been destroyed"),
/// Failed to create thread pool.
PoolCreation(e: String) {
description("Failed to create thread pool!")
display("Thread pool creation failed: {}", e)
}
/// An error occuring in buffer/texture updates.
BufTexUpdate {
description("An error occured during buffer/texture update")
}
/// No global with given name could be found.
MissingGlobal(name: String) {
description("No global was found with the given name")
display(r#"No global was found with the name "{}""#, name)
}
/// No buffer with given name could be found.
MissingBuffer(name: String) {
description("No buffer was found with the given name")
display(r#"No buffer was found with the name "{}""#, name)
}
/// No constant buffer with given name could be found.
MissingConstBuffer(name: String) {
description("No constant buffer was found with the given name")
display(r#"No constant buffer was found with the name "{}""#, name)
}
/// A list of all errors that occured during render
DrawErrors(errors: Vec<Error>) {
description("One or more errors occured during drawing")
display("One or more errors occured during drawing: {:?}", errors)
}
/// The window handle associated with the renderer has been destroyed.
WindowDestroyed {
description("Window has been destroyed!")
}
}
}

impl From<gfx::CombinedError> for Error {
fn from(e: gfx::CombinedError) -> Error {
Error::TargetCreation(e)
}
}

impl From<gfx::PipelineStateError<String>> for Error {
fn from(e: gfx::PipelineStateError<String>) -> Error {
Error::PassInit(e)
}
}

impl From<gfx::ResourceViewError> for Error {
fn from(e: gfx::ResourceViewError) -> Error {
Error::ResViewCreation(e)
}
}

impl From<gfx::buffer::CreationError> for Error {
fn from(e: gfx::buffer::CreationError) -> Error {
Error::BufferCreation(e)
}
}

impl From<gfx::shade::ProgramError> for Error {
fn from(e: gfx::shade::ProgramError) -> Error {
Error::ProgramCreation(e)
}
}

impl From<gfx::texture::CreationError> for Error {
fn from(e: gfx::texture::CreationError) -> Error {
Error::TextureCreation(e)
}
}

impl From<gfx_core::pso::CreationError> for Error {
fn from(e: gfx_core::pso::CreationError) -> Error {
Error::PipelineCreation(e)
}
}