@@ -26,6 +26,7 @@ use webxr_api::MockViewsInit;
2626use webxr_api:: Native ;
2727use webxr_api:: Quitter ;
2828use webxr_api:: Receiver ;
29+ use webxr_api:: SelectEvent ;
2930use webxr_api:: Sender ;
3031use webxr_api:: Session ;
3132use webxr_api:: SessionMode ;
@@ -52,6 +53,7 @@ struct InputInfo {
5253 active : bool ,
5354 pointer : Option < RigidTransform3D < f32 , Input , Native > > ,
5455 grip : Option < RigidTransform3D < f32 , Input , Native > > ,
56+ clicking : bool ,
5557}
5658
5759struct HeadlessDevice {
@@ -170,41 +172,22 @@ impl DeviceAPI<Surface> for HeadlessDevice {
170172
171173 fn wait_for_animation_frame ( & mut self ) -> Option < Frame > {
172174 thread:: sleep ( std:: time:: Duration :: from_millis ( 20 ) ) ;
173- let time_ns = time:: precise_time_ns ( ) ;
174175 let mut data = self . data . lock ( ) . unwrap ( ) ;
175- let transform = data. viewer_origin ;
176- let inputs = data
177- . inputs
178- . iter ( )
179- . filter ( |i| i. active )
180- . map ( |i| InputFrame {
181- id : i. source . id ,
182- target_ray_origin : i. pointer ,
183- grip_origin : i. grip ,
184- pressed : false ,
185- squeezed : false ,
186- } )
187- . collect ( ) ;
188-
189- let mut events = if data. needs_view_update {
176+ let mut frame = data. get_frame ( ) ;
177+ if data. needs_view_update {
190178 data. needs_view_update = false ;
191- vec ! [ FrameUpdateEvent :: UpdateViews ( self . views ( ) ) ]
192- } else {
193- vec ! [ ]
179+ frame
180+ . events
181+ . push ( FrameUpdateEvent :: UpdateViews ( self . views ( ) ) )
194182 } ;
195183
196184 if data. needs_floor_update {
197- events. push ( FrameUpdateEvent :: UpdateFloorTransform (
185+ frame . events . push ( FrameUpdateEvent :: UpdateFloorTransform (
198186 data. floor_transform . clone ( ) ,
199187 ) ) ;
200188 data. needs_floor_update = false ;
201189 }
202- Some ( Frame {
203- transform,
204- inputs,
205- events,
206- time_ns,
207- } )
190+ Some ( frame)
208191 }
209192
210193 fn render_animation_frame ( & mut self , surface : Surface ) -> Surface {
@@ -240,6 +223,30 @@ impl HeadlessMockDiscovery {
240223}
241224
242225impl HeadlessDeviceData {
226+ fn get_frame ( & self ) -> Frame {
227+ let time_ns = time:: precise_time_ns ( ) ;
228+ let transform = self . viewer_origin ;
229+ let inputs = self
230+ . inputs
231+ . iter ( )
232+ . filter ( |i| i. active )
233+ . map ( |i| InputFrame {
234+ id : i. source . id ,
235+ target_ray_origin : i. pointer ,
236+ grip_origin : i. grip ,
237+ pressed : false ,
238+ squeezed : false ,
239+ } )
240+ . collect ( ) ;
241+
242+ Frame {
243+ transform,
244+ inputs,
245+ events : vec ! [ ] ,
246+ time_ns,
247+ }
248+ }
249+
243250 fn handle_msg ( & mut self , msg : MockDeviceMsg ) -> bool {
244251 match msg {
245252 MockDeviceMsg :: SetViewerOrigin ( viewer_origin) => {
@@ -253,18 +260,14 @@ impl HeadlessDeviceData {
253260 self . views = views;
254261 self . needs_view_update = true ;
255262 }
256- MockDeviceMsg :: Focus => {
257- // TODO
258- }
259- MockDeviceMsg :: Blur => {
260- // TODO
261- }
263+ MockDeviceMsg :: VisibilityChange ( v) => self . events . callback ( Event :: VisibilityChange ( v) ) ,
262264 MockDeviceMsg :: AddInputSource ( init) => {
263265 self . inputs . push ( InputInfo {
264266 source : init. source ,
265267 pointer : init. pointer_origin ,
266268 grip : init. grip_origin ,
267269 active : true ,
270+ clicking : false ,
268271 } ) ;
269272 self . events . callback ( Event :: AddInput ( init. source ) )
270273 }
@@ -275,8 +278,63 @@ impl HeadlessDeviceData {
275278 MockInputMsg :: SetTargetRayMode ( t) => input. source . target_ray_mode = t,
276279 MockInputMsg :: SetPointerOrigin ( p) => input. pointer = p,
277280 MockInputMsg :: SetGripOrigin ( p) => input. grip = p,
278- MockInputMsg :: Disconnect => input. active = false ,
279- MockInputMsg :: Reconnect => input. active = true ,
281+ MockInputMsg :: TriggerSelect ( kind, event) => {
282+ if !input. active {
283+ return true ;
284+ }
285+ let clicking = input. clicking ;
286+ input. clicking = event == SelectEvent :: Start ;
287+ let frame = self . get_frame ( ) ;
288+ match event {
289+ SelectEvent :: Start => {
290+ self . events . callback ( Event :: Select ( id, kind, event, frame) ) ;
291+ }
292+ SelectEvent :: End => {
293+ if clicking {
294+ self . events . callback ( Event :: Select (
295+ id,
296+ kind,
297+ SelectEvent :: Select ,
298+ frame,
299+ ) ) ;
300+ } else {
301+ self . events . callback ( Event :: Select (
302+ id,
303+ kind,
304+ SelectEvent :: End ,
305+ frame,
306+ ) ) ;
307+ }
308+ }
309+ SelectEvent :: Select => {
310+ self . events . callback ( Event :: Select (
311+ id,
312+ kind,
313+ SelectEvent :: Start ,
314+ frame. clone ( ) ,
315+ ) ) ;
316+ self . events . callback ( Event :: Select (
317+ id,
318+ kind,
319+ SelectEvent :: Select ,
320+ frame,
321+ ) ) ;
322+ }
323+ }
324+ }
325+ MockInputMsg :: Disconnect => {
326+ if input. active {
327+ self . events . callback ( Event :: RemoveInput ( input. source . id ) ) ;
328+ input. active = false ;
329+ input. clicking = false ;
330+ }
331+ }
332+ MockInputMsg :: Reconnect => {
333+ if !input. active {
334+ self . events . callback ( Event :: AddInput ( input. source ) ) ;
335+ input. active = true ;
336+ }
337+ }
280338 }
281339 }
282340 }
0 commit comments