mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-23 16:49:31 +00:00
implemented error wrapper
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
[root]
|
[root]
|
||||||
name = "openvr"
|
name = "openvr"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glium 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"nalgebra 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "openvr"
|
name = "openvr"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
authors = [
|
authors = [
|
||||||
"Colin Sherratt",
|
"Colin Sherratt",
|
||||||
"Erick Tryzelaar",
|
"Erick Tryzelaar",
|
||||||
|
123
src/error.rs
Normal file
123
src/error.rs
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ pub use openvr_sys::Enum_ETrackedDeviceProperty::*;
|
|||||||
pub use openvr_sys::Enum_ETrackedDeviceClass::*;
|
pub use openvr_sys::Enum_ETrackedDeviceClass::*;
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
pub mod error;
|
||||||
pub mod tracking;
|
pub mod tracking;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
pub mod extended_display;
|
pub mod extended_display;
|
||||||
@ -18,11 +19,12 @@ pub use compositor::IVRCompositor;
|
|||||||
pub use render_models::IVRRenderModels;
|
pub use render_models::IVRRenderModels;
|
||||||
|
|
||||||
pub use subsystems::*;
|
pub use subsystems::*;
|
||||||
|
pub use error::*;
|
||||||
|
|
||||||
pub use common::Eye;
|
pub use common::Eye;
|
||||||
|
|
||||||
/// Inits the open vr interface and returns the system
|
/// 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 mut err = EVRInitError_VRInitError_None;
|
||||||
let app_type = EVRApplicationType_VRApplication_Scene;
|
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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,31 @@ use std::string::String;
|
|||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use subsystems::render_models;
|
use subsystems::render_models;
|
||||||
|
use error::*;
|
||||||
|
|
||||||
pub struct IVRRenderModels(*const ());
|
pub struct IVRRenderModels(*const ());
|
||||||
|
|
||||||
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
|
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
|
||||||
pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_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 {
|
impl Drop for RenderModel {
|
||||||
/// will inform openvr that the memory for the render model is no longer required
|
/// will inform openvr that the memory for the render model is no longer required
|
||||||
fn drop (&mut self) {
|
fn drop (&mut self) {
|
||||||
@ -54,7 +73,7 @@ impl RenderModel {
|
|||||||
|
|
||||||
/// asynchronosly loads the texture for the current render model
|
/// asynchronosly loads the texture for the current render model
|
||||||
/// see IVRRenderModels::load_async for info how openvr async work
|
/// 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 {
|
unsafe {
|
||||||
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
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();
|
let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut();
|
||||||
@ -69,7 +88,7 @@ impl RenderModel {
|
|||||||
Ok(RenderModelTexture (resp))
|
Ok(RenderModelTexture (resp))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
Err(err)
|
Err(Error::from_raw(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +96,7 @@ impl RenderModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// loads the texture for current model
|
/// 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;
|
use std;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -87,13 +106,8 @@ impl RenderModel {
|
|||||||
return Ok(texture);
|
return Ok(texture);
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
match err {
|
if !err.is_loading() {
|
||||||
EVRRenderModelError_VRRenderModelError_Loading => {
|
return Err(err);
|
||||||
// ask again later
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +172,7 @@ impl IVRRenderModels {
|
|||||||
|
|
||||||
/// Loads an render model into local memory
|
/// Loads an render model into local memory
|
||||||
/// blocks the thread and waits until driver responds with model
|
/// 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;
|
use std;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -168,13 +182,8 @@ impl IVRRenderModels {
|
|||||||
return Ok(model);
|
return Ok(model);
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
match err {
|
if !err.is_loading() {
|
||||||
EVRRenderModelError_VRRenderModelError_Loading => {
|
return Err(err);
|
||||||
// ask again later
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +195,7 @@ impl IVRRenderModels {
|
|||||||
/// When called for the first time openvr will start to load the model into memory
|
/// 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
|
/// 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()
|
/// 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;
|
use std;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -207,7 +216,7 @@ impl IVRRenderModels {
|
|||||||
Ok(RenderModel ( resp ))
|
Ok(RenderModel ( resp ))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
Err(err)
|
Err(Error::from_raw(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
extern crate openvr_sys;
|
extern crate openvr_sys;
|
||||||
use openvr_sys::Enum_EVRInitError::*;
|
use openvr_sys::Enum_EVRInitError::*;
|
||||||
|
|
||||||
|
use error::*;
|
||||||
use system::IVRSystem;
|
use system::IVRSystem;
|
||||||
use extended_display::IVRExtendedDisplay;
|
use extended_display::IVRExtendedDisplay;
|
||||||
use compositor::IVRCompositor;
|
use compositor::IVRCompositor;
|
||||||
@ -9,7 +10,7 @@ use render_models::IVRRenderModels;
|
|||||||
use std;
|
use std;
|
||||||
|
|
||||||
/// gets the current vr system interface (initialization is required beforehand)
|
/// 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 mut err = EVRInitError_VRInitError_None;
|
||||||
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
|
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
|
||||||
let ptr = unsafe {
|
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)
|
/// 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 mut err = EVRInitError_VRInitError_None;
|
||||||
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
|
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
|
||||||
let ptr = unsafe {
|
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)
|
/// 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 mut err = EVRInitError_VRInitError_None;
|
||||||
let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap();
|
let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap();
|
||||||
let ptr = unsafe {
|
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)
|
/// 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 mut err = EVRInitError_VRInitError_None;
|
||||||
let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap();
|
let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap();
|
||||||
let ptr = unsafe {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use openvr_sys;
|
use openvr_sys;
|
||||||
use openvr_sys::Enum_ETrackedPropertyError::*;
|
use openvr_sys::Enum_ETrackedPropertyError::*;
|
||||||
|
|
||||||
use subsystems::*;
|
use subsystems::*;
|
||||||
|
use error::*;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct TrackedDevicePose {
|
pub struct TrackedDevicePose {
|
||||||
@ -22,7 +24,7 @@ impl TrackedDevicePose {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// gets a propery as a string
|
/// 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 {
|
unsafe {
|
||||||
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
|
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ impl TrackedDevicePose {
|
|||||||
if size > 0 {
|
if size > 0 {
|
||||||
return Ok(String::from_raw_parts(val_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize));
|
return Ok(String::from_raw_parts(val_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize));
|
||||||
} else {
|
} else {
|
||||||
return Err(err);
|
return Err(Error::from_raw(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user