diff --git a/lib.rs b/lib.rs index 4d5c4aa..dea6b96 100644 --- a/lib.rs +++ b/lib.rs @@ -4,8 +4,9 @@ extern mod cgmath; -use std::libc::{c_float, time_t}; +use std::libc::{c_float, time_t, c_void}; use std::c_str::ToCStr; +use std::cast::transmute; use cgmath::quaternion::Quat; use cgmath::vector::Vec3; @@ -24,7 +25,7 @@ use cgmath::angle::rad; extern {} pub mod ll { - use std::libc::{c_uint, c_int, c_float, c_long, c_char, time_t}; + use std::libc::{c_uint, c_int, c_float, c_long, c_char, time_t, c_void}; pub enum DeviceManager {} pub struct HMDInfo { @@ -47,6 +48,7 @@ pub mod ll { pub enum HMDDevice {} pub enum SensorDevice {} pub enum SensorFusion {} + pub enum MessageHandler {} pub struct Vector3f {x: c_float, y: c_float, z: c_float} pub struct Quatf {x: c_float, y: c_float, z: c_float, w: c_float} @@ -55,12 +57,29 @@ pub mod ll { m31: c_float, m32: c_float, m33: c_float, m34: c_float, m41: c_float, m42: c_float, m43: c_float, m44: c_float} + pub struct MessageBodyFrame { + Acceleration: Vector3f, + RotationRate: Vector3f, + MagneticField: Vector3f, + Temperature: f32, + TimeDelta: f32, + } + extern "C" { pub fn OVR_system_init(); pub fn OVR_DeviceManager_Create() -> *DeviceManager; pub fn OVR_DeviceManager_EnumerateDevices(dm :*DeviceManager) -> *HMDDevice; - pub fn OVR_HDMDevice_GetDeviceInfo(hmd: *HMDDevice) -> HMDInfo; - pub fn OVR_HDMDevice_GetSensor(hmd: *HMDDevice) -> *SensorDevice; + pub fn OVR_DeviceManager_drop(dm: *DeviceManager); + + pub fn OVR_HMDDevice_GetDeviceInfo(hmd: *HMDDevice) -> HMDInfo; + pub fn OVR_HMDDevice_GetSensor(hmd: *HMDDevice) -> *SensorDevice; + + pub fn OVR_MessageHandler(ptr: *c_void, cb: extern "C" fn(ptr: *c_void, msg: *MessageBodyFrame)) -> *MessageHandler; + pub fn OVR_MessageHandler_move_ptr(mh: *MessageHandler) -> *c_void; + pub fn OVR_MessageHandler_drop(mh: *MessageHandler); + + pub fn OVR_SensorDevice_SetMessageHandler(sd: *SensorDevice, mh: *MessageHandler); + pub fn OVR_SensorDevice_drop(sd: *SensorDevice); pub fn OVR_SensorFusion() -> *SensorFusion; pub fn OVR_SensorFusion_AttachToSensor(sf: *SensorFusion, sd: *SensorDevice) -> bool; @@ -94,8 +113,9 @@ pub mod ll { pub fn OVR_SensorFusion_ClearMagCalibration(sf: *SensorFusion); pub fn OVR_SensorFusion_ClearMagReferences(sf: *SensorFusion, rawMag: *Vector3f); pub fn OVR_SensorFusion_GetCalibratedMagValue(sf: *SensorFusion) -> Vector3f; - //pub fn OVR_SensorFusion_OnMessage(sf: *SensorFusion, msg: *MessageBodyFrame) + pub fn OVR_SensorFusion_OnMessage(sf: *SensorFusion, msg: *MessageBodyFrame); //pub fn OVR_SensorFusion_SetDelegateMessageHandler(sf: *SensorFusion, handle: *MessageHandler) + pub fn OVR_SensorFusion_drop(sf: *SensorFusion); } } @@ -111,6 +131,15 @@ pub struct DeviceManager { priv ptr: *ll::DeviceManager } +impl Drop for DeviceManager { + fn drop(&mut self) + { + unsafe { + ll::OVR_DeviceManager_drop(self.ptr); + } + } +} + impl DeviceManager { pub fn new() -> Option { @@ -153,7 +182,7 @@ impl HMDDevice { unsafe { println!("{:?}", self); HMDInfo{ - dat: ll::OVR_HDMDevice_GetDeviceInfo(self.ptr) + dat: ll::OVR_HMDDevice_GetDeviceInfo(self.ptr) } } } @@ -162,13 +191,14 @@ impl HMDDevice { { unsafe { println!("{:?}", self); - let ptr = ll::OVR_HDMDevice_GetSensor(self.ptr); + let ptr = ll::OVR_HMDDevice_GetSensor(self.ptr); if ptr.is_null() { None } else { Some(SensorDevice{ - ptr: ptr + ptr: ptr, + msg: None }) } } @@ -249,6 +279,14 @@ pub struct SensorFusion { priv ptr: *ll::SensorFusion } +impl Drop for SensorFusion { + fn drop(&mut self) { + unsafe { + ll::OVR_SensorFusion_drop(self.ptr); + } + } +} + impl SensorFusion { pub fn new() -> Option { @@ -501,10 +539,91 @@ impl SensorFusion { Vec3::new(vec.x, vec.y, vec.z) } } + + pub fn on_message(&self, msg: &Message) + { + unsafe { + match *msg { + MsgBody(ref body) => { + ll::OVR_SensorFusion_OnMessage(self.ptr, transmute(body)); + } + } + } + } +} + +extern "C" fn chan_callback(chan: *c_void, msg: *ll::MessageBodyFrame) +{ + if chan.is_null() || msg.is_null() { + return; + } + + unsafe { + let chan: &Chan = transmute(chan); + let msg: &ll::MessageBodyFrame = transmute(msg); + + chan.send(MsgBody(MessageBody::from_raw(msg))); + } } pub struct SensorDevice { - priv ptr: *ll::SensorDevice + priv ptr: *ll::SensorDevice, + priv msg: Option<*ll::MessageHandler> +} + +impl Drop for SensorDevice +{ + fn drop(&mut self) + { + unsafe { + // free chan + match self.msg { + Some(msg) => { + let chan = ll::OVR_MessageHandler_move_ptr(msg); + let _: ~Chan = transmute(chan); + ll::OVR_MessageHandler_drop(msg); + }, + None => () + } + + ll::OVR_SensorDevice_drop(self.ptr); + } + } +} + +impl SensorDevice { + pub fn register_chan(&mut self, chan: ~Chan) + { + if self.msg.is_none() { + unsafe { + self.msg = Some(ll::OVR_MessageHandler(transmute(chan), chan_callback)); + let msg = self.msg.as_ref().unwrap(); + + ll::OVR_SensorDevice_SetMessageHandler(self.ptr, *msg); + } + } + } +} + +struct MessageBody { + acceleration: Vec3, + rotation_rate: Vec3, + magnetic_field: Vec3, + temperature: f32, + time_delta: f32 +} + +impl MessageBody { + fn from_raw(mbf: &ll::MessageBodyFrame) -> MessageBody + { + unsafe { + transmute(*mbf) + } + } +} + +pub enum Message { + MsgBody(MessageBody) } diff --git a/wrapper.cpp b/wrapper.cpp index e580c31..5f9e0a6 100644 --- a/wrapper.cpp +++ b/wrapper.cpp @@ -34,6 +34,59 @@ extern "C" long DisplayId; }; + struct MessageBodyFrame { + struct Vector3f Acceleration; + struct Vector3f RotationRate; + struct Vector3f MagneticField; + float Temperature; + float TimeDelta; + }; + + + class RustMessageHandler : public OVR::MessageHandler + { + public: + RustMessageHandler(void *_ptr, void (*_BodyFrame)(void *ptr, struct MessageBodyFrame *msg)) { + ptr = _ptr; + BodyFrame = _BodyFrame; + } + + void OnMessage(const OVR::Message& msg) + { + if (msg.Type == OVR::Message_BodyFrame) { + const OVR::MessageBodyFrame& bf = static_cast(msg); + struct MessageBodyFrame mbf = { + {bf.Acceleration.x, bf.Acceleration.y, bf.Acceleration.z}, + {bf.RotationRate.x, bf.RotationRate.y, bf.RotationRate.z}, + {bf.MagneticField.x, bf.MagneticField.y, bf.MagneticField.z}, + bf.Temperature, + bf.TimeDelta + }; + BodyFrame(ptr, &mbf); + + } + } + void *ptr; + void (*BodyFrame)(void *ptr, struct MessageBodyFrame *msg); + }; + + RustMessageHandler* OVR_MessageHandler(void *_ptr, void (*_BodyFrame)(void *ptr, struct MessageBodyFrame *msg)) + { + return new RustMessageHandler(_ptr, _BodyFrame); + } + + void* OVR_MessageHandler_move_ptr(RustMessageHandler* mh) + { + void *ptr = mh->ptr; + mh->ptr = NULL; + return ptr; + } + + void OVR_MessageHandler_drop(RustMessageHandler* mh) + { + delete mh; + } + void OVR_system_init(void) { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); @@ -44,12 +97,17 @@ extern "C" return OVR::DeviceManager::Create(); } + void OVR_DeviceManager_drop(OVR::DeviceManager *dm) + { + delete dm; + } + OVR::HMDDevice* OVR_DeviceManager_EnumerateDevices(OVR::DeviceManager* pManager) { return pManager->EnumerateDevices().CreateDevice(); } - struct HMDInfoC OVR_HDMDevice_GetDeviceInfo(OVR::HMDDevice* pHMD) + struct HMDInfoC OVR_HMDDevice_GetDeviceInfo(OVR::HMDDevice* pHMD) { OVR::HMDInfo hmd; struct HMDInfoC out_hmd; @@ -73,11 +131,21 @@ extern "C" return out_hmd; } - OVR::SensorDevice* OVR_HDMDevice_GetSensor(OVR::HMDDevice* pHMD) + OVR::SensorDevice* OVR_HMDDevice_GetSensor(OVR::HMDDevice* pHMD) { return pHMD->GetSensor(); } + void OVR_SensorDevice_drop(OVR::SensorDevice* sd) + { + delete sd; + } + + void OVR_SensorDevice_SetMessageHandler(OVR::SensorDevice* sensor, RustMessageHandler* mh) + { + sensor->SetMessageHandler(mh); + } + OVR::SensorFusion* OVR_SensorFusion(OVR::HMDDevice* pHMD) { OVR::SensorFusion* SFusion = new OVR::SensorFusion; @@ -268,73 +336,22 @@ extern "C" return (*SFusion).AttachToSensor(pSensor); } - unsigned OVR_HMDInfo_GetScreenHResolution(OVR::HMDInfo* info) + void OVR_SensorFusion_OnMessage(OVR::SensorFusion* SFusion, const MessageBodyFrame *msg) { - return info->HResolution; + OVR::MessageBodyFrame sensor(NULL); + + sensor.TimeDelta = msg->TimeDelta; + sensor.Temperature = msg->Temperature; + + sensor.Acceleration = OVR::Vector3f(msg->Acceleration.x, msg->Acceleration.y, msg->Acceleration.z); + sensor.RotationRate = OVR::Vector3f(msg->RotationRate.x, msg->RotationRate.y, msg->RotationRate.z); + sensor.MagneticField = OVR::Vector3f(msg->MagneticField.x, msg->MagneticField.y, msg->MagneticField.z); + + SFusion->OnMessage(sensor); } - unsigned OVR_HMDInfo_GetScreenVResolution(OVR::HMDInfo* info) + void OVR_SensorFusion_drop(OVR::SensorFusion *sf) { - return info->VResolution; - } - - float OVR_HMDInfo_GetHScreenSize(OVR::HMDInfo* info) - { - return info->HScreenSize; - } - - float OVR_HMDInfo_GetVScreenSize(OVR::HMDInfo* info) - { - return info->VScreenSize; - } - - float OVR_HMDInfo_GetVScreenCenter(OVR::HMDInfo* info) - { - return info->VScreenCenter; - } - - float OVR_HMDInfo_GetEyeToScreenDistance(OVR::HMDInfo* info) - { - return info->EyeToScreenDistance; - } - - float OVR_HMDInfo_GetLensSeparationDistance(OVR::HMDInfo* info) - { - return info->LensSeparationDistance; - } - - float OVR_HMDInfo_GetInterpupillaryDistance(OVR::HMDInfo* info) - { - return info->InterpupillaryDistance; - } - - float OVR_HMDInfo_GetDistortionK(OVR::HMDInfo* info, int idx) - { - return info->DistortionK[idx]; - } - - float OVR_HMDInfo_GetChromaAbCorrection(OVR::HMDInfo* info, int idx) - { - return info->ChromaAbCorrection[idx]; - } - - unsigned OVR_HMDInfo_GetDesktopX(OVR::HMDInfo* info) - { - return info->HResolution; - } - - unsigned OVR_HMDInfo_GetDesktopY(OVR::HMDInfo* info) - { - return info->DesktopY; - } - - char* OVR_HMDInfo_GetDisplayDeviceName(OVR::HMDInfo* info) - { - return info->DisplayDeviceName; - } - - long OVR_HMDInfo_GetDisplayId(OVR::HMDInfo* info) - { - return info->DisplayId; + delete sf; } } \ No newline at end of file