rust_webvr/
vr_manager.rs

1use std::collections::HashMap;
2use VRDisplayPtr;
3use VREvent;
4use VRGamepadPtr;
5use VRService;
6use VRServiceCreator;
7
8#[cfg(target_os = "android")]
9#[cfg(feature = "googlevr")]
10use api::GoogleVRServiceCreator;
11
12#[cfg(target_os = "windows")]
13#[cfg(feature = "openvr")]
14use api::OpenVRServiceCreator;
15
16#[cfg(target_os = "android")]
17#[cfg(feature = "oculusvr")]
18use api::OculusVRServiceCreator;
19
20#[cfg(feature = "mock")]
21use api::{MockServiceCreator, MockVRControlMsg, MockVRInit};
22
23#[cfg(feature = "vrexternal")]
24use api::VRExternalShmemPtr;
25
26#[cfg(target_os = "android")]
27#[cfg(feature = "vrexternal")]
28use api::VRExternalServiceCreator;
29
30// Single entry point all the VRServices and displays
31pub struct VRServiceManager {
32    initialized: bool,
33    services: Vec<Box<dyn VRService>>,
34    displays: HashMap<u32, VRDisplayPtr>,
35    gamepads: HashMap<u32, VRGamepadPtr>
36}
37
38unsafe impl Send for VRServiceManager {}
39
40impl Drop for VRServiceManager {
41     fn drop(&mut self) {
42         self.gamepads.clear();
43         self.displays.clear();
44         self.services.clear();
45     }
46}
47
48impl VRServiceManager {
49    pub fn new() -> VRServiceManager {
50        VRServiceManager {
51            initialized: false,
52            services: Vec::new(),
53            displays: HashMap::new(),
54            gamepads: HashMap::new()
55        }
56    }
57
58    // Register default VR services specified in crate's features
59    pub fn register_defaults(&mut self) {
60        let creators: Vec<Box<dyn VRServiceCreator>> = vec!(
61            #[cfg(target_os = "windows")]
62            #[cfg(feature = "openvr")]
63            OpenVRServiceCreator::new(),
64            #[cfg(target_os = "android")]
65            #[cfg(feature = "googlevr")]
66            GoogleVRServiceCreator::new(),
67            #[cfg(target_os = "android")]
68            #[cfg(feature = "oculusvr")]
69            OculusVRServiceCreator::new(),
70        );
71        
72        for creator in &creators {
73            self.register(creator.new_service());
74        }
75    }
76
77    // Register VRExternal service.
78    #[cfg(target_os = "android")]
79    #[cfg(feature = "vrexternal")]
80    pub fn register_vrexternal(&mut self, ptr: VRExternalShmemPtr) {
81        let creator = VRExternalServiceCreator::new(ptr);
82        self.register(creator.new_service());
83    }
84
85    // Register VRExternal service.
86    #[cfg(not(target_os = "android"))]
87    #[cfg(feature = "vrexternal")]
88    pub fn register_vrexternal(&mut self, _: VRExternalShmemPtr) {
89        unimplemented!();
90    }
91
92    // Register mock VR Service
93    // Usefull for testing
94    #[cfg(feature = "mock")]
95    pub fn register_mock(&mut self) {
96        let creator = MockServiceCreator::new();
97        self.register(creator.new_service());
98    }
99
100    // Register mock VR Service
101    // Usefull for testing
102    #[cfg(feature = "mock")]
103    pub fn register_mock_with_remote(&mut self, init: MockVRInit) -> std::sync::mpsc::Sender<MockVRControlMsg> {
104        let (service, remote) = MockServiceCreator::new_service_with_remote(init);
105        self.register(service);
106        remote
107    }
108
109    // Register a new VR service
110    pub fn register(&mut self, service: Box<dyn VRService>) {
111        self.services.push(service);
112    }
113    
114    // Initializes all the services
115    pub fn initialize_services(&mut self) {
116        if self.initialized {
117            return;
118        }
119
120        for service in &mut self.services {
121            if let Err(msg) = service.initialize() {
122                error!("Error initializing VRService: {:?}", msg);
123            }
124        }
125        self.initialized = true;
126    }
127
128    pub fn get_displays(&mut self) -> Vec<VRDisplayPtr> {
129        self.fetch_displays();
130        let mut result = Vec::new();
131        for (_, display) in &self.displays {
132            result.push(display.clone());
133        }
134        // Sort by display_id to match service initialization order
135        result.sort_by(|a, b| a.borrow().id().cmp(&b.borrow().id()));
136        result
137    }
138
139    pub fn get_gamepads(&mut self) -> Vec<VRGamepadPtr> {
140        self.fetch_gamepads();
141        let mut result = Vec::new();
142        for (_, gamepad) in &self.gamepads {
143            result.push(gamepad.clone());
144        }
145        // Sort by gamepad_id to match service initialization order
146        result.sort_by(|a, b| a.borrow().id().cmp(&b.borrow().id()));
147        result
148    }
149
150    pub fn get_display(&self, display_id: u32) -> Option<&VRDisplayPtr> {
151        self.displays.get(&display_id)
152    }
153
154    pub fn poll_events(&mut self) -> Vec<VREvent> {
155        let mut events = Vec::new();
156        for service in &mut self.services {
157            events.append(&mut service.poll_events());
158        }
159        events
160    }
161
162    pub fn is_initialized(&self) -> bool {
163        self.initialized
164    }
165}
166
167impl VRServiceManager {
168    fn fetch_displays(&mut self) {
169        self.initialize_services();
170
171        for service in &mut self.services {
172            let displays = service.fetch_displays();
173            if let Ok(displays) = displays {
174                for display in displays {
175                    let key = display.borrow().id();
176                    if !self.displays.contains_key(&key) {
177                        self.displays.insert(key, display.clone());
178                    }
179                }
180            }
181        }
182    }
183
184    fn fetch_gamepads(&mut self) {
185        self.initialize_services();
186
187        for service in &mut self.services {
188            let gamepads = service.fetch_gamepads();
189            if let Ok(gamepads) = gamepads {
190                for gamepad in gamepads {
191                    let key = gamepad.borrow().id();
192                    if !self.gamepads.contains_key(&key) {
193                        self.gamepads.insert(key, gamepad.clone());
194                    }
195                }
196            }
197        }
198    }
199}