@@ -278,15 +278,113 @@ impl GilGamepad {
278278 pub fn new_from_config ( config : GilGamepadConfig ) -> Self {
279279 Self :: new ( config. device_id , config. map )
280280 }
281+
282+ /// This is another implementation for send command all the times
283+ pub fn new_to_send_constantly ( id : usize , map : Map , time_step : f64 , timeout : f64 ) -> Self {
284+ let ( tx, rx) = flume:: unbounded ( ) ;
285+ let is_running = Arc :: new ( AtomicBool :: new ( true ) ) ;
286+ let is_running_cloned = is_running. clone ( ) ;
287+ std:: thread:: spawn ( move || {
288+ let mut gil = gilrs:: Gilrs :: new ( ) . unwrap ( ) ;
289+ #[ cfg_attr( target_os = "macos" , allow( unused_mut) ) ]
290+ let mut selected_gamepad_id = None ;
291+ // TODO: On macOS `gamepads()` does not works.
292+ #[ cfg( not( target_os = "macos" ) ) ]
293+ {
294+ let mut is_found = false ;
295+ for ( connected_id, gamepad) in gil. gamepads ( ) {
296+ info ! ( "{} is {:?}" , gamepad. name( ) , gamepad. power_info( ) ) ;
297+ if id == Into :: < usize > :: into ( connected_id) {
298+ is_found = true ;
299+ selected_gamepad_id = Some ( connected_id) ;
300+ }
301+ }
302+ if !is_found {
303+ panic ! ( "No Gamepad id={id} is found" ) ;
304+ }
305+ }
306+ let mut is_connected = true ;
307+ tx. send ( GamepadEvent :: Connected ) . unwrap ( ) ;
308+ let mut last_updated_time = std:: time:: Instant :: now ( ) ;
309+ let mut last_message = GamepadEvent :: Disconnected ;
310+ while is_running_cloned. load ( Ordering :: Relaxed ) {
311+ if let Some ( gamepad_id) = selected_gamepad_id {
312+ let gamepad = gil. gamepad ( gamepad_id) ;
313+ if is_connected && !gamepad. is_connected ( ) {
314+ error ! ( "gamepad [{}] is disconnected" , gamepad. name( ) ) ;
315+ is_connected = false ;
316+ tx. send ( GamepadEvent :: Disconnected ) . unwrap ( ) ;
317+ } else if !is_connected && gamepad. is_connected ( ) {
318+ info ! ( "gamepad [{}] is connected" , gamepad. name( ) ) ;
319+ is_connected = true ;
320+ tx. send ( GamepadEvent :: Connected ) . unwrap ( ) ;
321+ }
322+ }
323+
324+ match gil. next_event ( ) {
325+ Some ( gilrs:: Event {
326+ id : recv_id, event, ..
327+ } ) => {
328+ if id == Into :: < usize > :: into ( recv_id) {
329+ if let Some ( e) = map. convert_event ( event) {
330+ tx. send ( e. clone ( ) ) . unwrap ( ) ;
331+ last_updated_time = std:: time:: Instant :: now ( ) ;
332+ last_message = e;
333+ }
334+ }
335+ }
336+ None => {
337+ if timeout. is_normal ( )
338+ && timeout. is_sign_positive ( )
339+ && last_updated_time. elapsed ( ) . as_secs_f64 ( ) < timeout
340+ {
341+ tx. send ( last_message. clone ( ) ) . unwrap ( )
342+ } else {
343+ // Timeout... Pass through...
344+ info ! ( "Command timeout..." )
345+ }
346+ }
347+ }
348+
349+ std:: thread:: sleep ( Duration :: from_secs_f64 ( time_step) ) ;
350+ }
351+ } ) ;
352+
353+ Self { rx, is_running }
354+ }
355+
356+ pub fn new_from_config_to_send_constantly ( config : GilGamepadConfig ) -> Self {
357+ Self :: new_to_send_constantly (
358+ config. device_id ,
359+ config. map ,
360+ config. time_step ,
361+ config. timeout ,
362+ )
363+ }
281364}
282365
283- #[ derive( Debug , Serialize , Deserialize , Clone , Default , JsonSchema ) ]
366+ #[ derive( Debug , Serialize , Deserialize , Clone , JsonSchema ) ]
284367#[ serde( deny_unknown_fields) ]
285368pub struct GilGamepadConfig {
286369 #[ serde( default ) ]
287370 device_id : usize ,
288371 #[ serde( default ) ]
289372 map : Map ,
373+ #[ serde( default ) ]
374+ time_step : f64 ,
375+ #[ serde( default ) ]
376+ timeout : f64 ,
377+ }
378+
379+ impl Default for GilGamepadConfig {
380+ fn default ( ) -> Self {
381+ Self {
382+ device_id : usize:: default ( ) ,
383+ map : Map :: default ( ) ,
384+ time_step : 0.01 ,
385+ timeout : 0.5 ,
386+ }
387+ }
290388}
291389
292390#[ async_trait]
0 commit comments