implemented error wrapper

This commit is contained in:
Rene Eichhorn
2016-05-06 19:31:04 +02:00
parent f085d27003
commit e89b43216b
7 changed files with 171 additions and 34 deletions

2
Cargo.lock generated
View File

@ -1,6 +1,6 @@
[root]
name = "openvr"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"glium 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nalgebra 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,6 +1,6 @@
[package]
name = "openvr"
version = "0.2.0"
version = "0.3.0"
authors = [
"Colin Sherratt",
"Erick Tryzelaar",

123
src/error.rs Normal file
View File

@ -0,0 +1,123 @@
use openvr_sys;
use subsystems::*;
pub trait RawError {
fn is_err(&self) -> bool;
fn message(&self) -> String;
}
#[derive(Debug)]
pub struct Error<Err: RawError + Copy> {
raw: Err
}
impl<Err: RawError + Copy> Error<Err> {
/// Creates a new error object using the raw openvr_sys error
pub fn from_raw(raw: Err) -> Self {
Error {
raw: raw
}
}
/// Turns managed error into raw enum from binding
pub fn to_raw(&self) -> Err {
self.raw
}
/// Gets an human-readable error message (if available)
pub fn message(&self) -> String {
self.raw.message()
}
/// Returns true when current object is not an error
pub fn is_ok(&self) -> bool {
!self.raw.is_err()
}
/// Return true when current object is an error
pub fn is_err(&self) -> bool {
self.raw.is_err()
}
}
// OpenVR implement per error type a new function to get a error string
// for easier use, this macro will generate easily the RawError trait
macro_rules! impl_raw_error {
($subsystem:ident, $fntable: ident, $get:ident, $raw_name:ident, $none_name:ident) => {
impl RawError for $raw_name {
fn is_err(&self) -> bool {
match *self {
$none_name => {
true
},
_ => {
false
}
}
}
fn message(&self) -> String {
let sstr = unsafe {
let sub = * { $subsystem().unwrap().0 as *mut openvr_sys::$fntable};
CStr::from_ptr(sub.$get.unwrap()(*self)).to_str().unwrap()
};
String::from(sstr)
}
}
}
}
use std::ffi::CStr;
use openvr_sys::*;
use openvr_sys::Enum_ETrackedPropertyError::*;
use openvr_sys::Enum_EVRInitError::*;
use openvr_sys::Enum_EVRRenderModelError::*;
impl_raw_error!(
system,
Struct_VR_IVRSystem_FnTable,
GetPropErrorNameFromEnum,
ETrackedPropertyError,
ETrackedPropertyError_TrackedProp_Success);
// The init error has some special function to retrieve string
impl RawError for Enum_EVRInitError {
fn is_err(&self) -> bool {
match *self {
EVRInitError_VRInitError_None => {
true
},
_ => {
false
}
}
}
fn message(&self) -> String {
let sstr = unsafe {
CStr::from_ptr(openvr_sys::VR_GetVRInitErrorAsEnglishDescription(*self)).to_str().unwrap()
};
String::from(sstr)
}
}
// RenderModelError has no implementation in 0.1.19 unfortunately
impl RawError for Enum_EVRRenderModelError {
fn is_err(&self) -> bool {
match *self {
EVRRenderModelError_VRRenderModelError_None => {
true
},
_ => {
false
}
}
}
fn message(&self) -> String {
String::from(format!("{:?}", *self))
}
}

View File

@ -5,6 +5,7 @@ pub use openvr_sys::Enum_ETrackedDeviceProperty::*;
pub use openvr_sys::Enum_ETrackedDeviceClass::*;
pub mod common;
pub mod error;
pub mod tracking;
pub mod system;
pub mod extended_display;
@ -18,11 +19,12 @@ pub use compositor::IVRCompositor;
pub use render_models::IVRRenderModels;
pub use subsystems::*;
pub use error::*;
pub use common::Eye;
/// Inits the open vr interface and returns the system
pub fn init() -> Result<system::IVRSystem, openvr_sys::HmdError> {
pub fn init() -> Result<system::IVRSystem, Error<openvr_sys::Enum_EVRInitError>> {
let mut err = EVRInitError_VRInitError_None;
let app_type = EVRApplicationType_VRApplication_Scene;
@ -46,7 +48,7 @@ pub fn init() -> Result<system::IVRSystem, openvr_sys::HmdError> {
}
},
_ => {
return Err(err);
return Err(Error::from_raw(err));
}
};
}

View File

@ -5,12 +5,31 @@ use std::string::String;
use std::ptr::null_mut;
use std::slice;
use subsystems::render_models;
use error::*;
pub struct IVRRenderModels(*const ());
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t);
trait AsyncError {
/// checks if result is currently loading
fn is_loading(&self) -> bool;
}
impl AsyncError for Error<openvr_sys::Enum_EVRRenderModelError> {
fn is_loading(&self) -> bool {
match self.to_raw() {
EVRRenderModelError_VRRenderModelError_Loading => {
true
},
_ => {
false
}
}
}
}
impl Drop for RenderModel {
/// will inform openvr that the memory for the render model is no longer required
fn drop (&mut self) {
@ -54,7 +73,7 @@ impl RenderModel {
/// asynchronosly loads the texture for the current render model
/// see IVRRenderModels::load_async for info how openvr async work
pub fn load_texture_async(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
pub fn load_texture_async(&self) -> Result<RenderModelTexture, Error<openvr_sys::Enum_EVRRenderModelError>> {
unsafe {
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut();
@ -69,7 +88,7 @@ impl RenderModel {
Ok(RenderModelTexture (resp))
},
_ => {
Err(err)
Err(Error::from_raw(err))
}
}
@ -77,7 +96,7 @@ impl RenderModel {
}
/// loads the texture for current model
pub fn load_texture(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
pub fn load_texture(&self) -> Result<RenderModelTexture, Error<openvr_sys::Enum_EVRRenderModelError>> {
use std;
loop {
@ -87,16 +106,11 @@ impl RenderModel {
return Ok(texture);
},
Err(err) => {
match err {
EVRRenderModelError_VRRenderModelError_Loading => {
// ask again later
},
_ => {
if !err.is_loading() {
return Err(err);
}
}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}
@ -158,7 +172,7 @@ impl IVRRenderModels {
/// Loads an render model into local memory
/// blocks the thread and waits until driver responds with model
pub fn load(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
pub fn load(&self, name: String) -> Result<RenderModel, Error<openvr_sys::EVRRenderModelError>> {
use std;
loop {
@ -168,16 +182,11 @@ impl IVRRenderModels {
return Ok(model);
},
Err(err) => {
match err {
EVRRenderModelError_VRRenderModelError_Loading => {
// ask again later
},
_ => {
if !err.is_loading() {
return Err(err);
}
}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}
@ -186,7 +195,7 @@ impl IVRRenderModels {
/// When called for the first time openvr will start to load the model into memory
/// In the mean time this call will respond with EVRRenderModelError_VRRenderModelError_Loading
/// It is designed to be used wihtin the render loop as it won't block the user, for sync usage use load()
pub fn load_async(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
pub fn load_async(&self, name: String) -> Result<RenderModel, Error<openvr_sys::EVRRenderModelError>> {
use std;
unsafe {
@ -207,7 +216,7 @@ impl IVRRenderModels {
Ok(RenderModel ( resp ))
},
_ => {
Err(err)
Err(Error::from_raw(err))
}
}

View File

@ -1,6 +1,7 @@
extern crate openvr_sys;
use openvr_sys::Enum_EVRInitError::*;
use error::*;
use system::IVRSystem;
use extended_display::IVRExtendedDisplay;
use compositor::IVRCompositor;
@ -9,7 +10,7 @@ use render_models::IVRRenderModels;
use std;
/// gets the current vr system interface (initialization is required beforehand)
pub fn system() -> Result<IVRSystem, openvr_sys::HmdError> {
pub fn system() -> Result<IVRSystem, Error<openvr_sys::Enum_EVRInitError>> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
let ptr = unsafe {
@ -23,13 +24,13 @@ pub fn system() -> Result<IVRSystem, openvr_sys::HmdError> {
}
},
_ => {
return Err(err);
return Err(Error::from_raw(err));
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn extended_display() -> Result<IVRExtendedDisplay, openvr_sys::HmdError> {
pub fn extended_display() -> Result<IVRExtendedDisplay, Error<openvr_sys::Enum_EVRInitError>> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
let ptr = unsafe {
@ -43,13 +44,13 @@ pub fn extended_display() -> Result<IVRExtendedDisplay, openvr_sys::HmdError> {
}
},
_ => {
return Err(err);
return Err(Error::from_raw(err));
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn compositor() -> Result<IVRCompositor, openvr_sys::HmdError> {
pub fn compositor() -> Result<IVRCompositor, Error<openvr_sys::Enum_EVRInitError>> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap();
let ptr = unsafe {
@ -63,13 +64,13 @@ pub fn compositor() -> Result<IVRCompositor, openvr_sys::HmdError> {
}
},
_ => {
return Err(err);
return Err(Error::from_raw(err));
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn render_models() -> Result<IVRRenderModels, openvr_sys::HmdError> {
pub fn render_models() -> Result<IVRRenderModels, Error<openvr_sys::Enum_EVRInitError>> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap();
let ptr = unsafe {
@ -83,7 +84,7 @@ pub fn render_models() -> Result<IVRRenderModels, openvr_sys::HmdError> {
}
},
_ => {
return Err(err);
return Err(Error::from_raw(err));
}
}
}

View File

@ -1,6 +1,8 @@
use openvr_sys;
use openvr_sys::Enum_ETrackedPropertyError::*;
use subsystems::*;
use error::*;
#[derive(Debug, Copy, Clone)]
pub struct TrackedDevicePose {
@ -22,7 +24,7 @@ impl TrackedDevicePose {
}
/// gets a propery as a string
pub fn get_property_string(&self, property: openvr_sys::Enum_ETrackedDeviceProperty) -> Result<String, openvr_sys::Enum_ETrackedPropertyError> {
pub fn get_property_string(&self, property: openvr_sys::Enum_ETrackedDeviceProperty) -> Result<String, Error<openvr_sys::Enum_ETrackedPropertyError>> {
unsafe {
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
@ -40,7 +42,7 @@ impl TrackedDevicePose {
if size > 0 {
return Ok(String::from_raw_parts(val_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize));
} else {
return Err(err);
return Err(Error::from_raw(err));
}
}
}