Struct ggez::input::gamepad::Gilrs

source ·
pub struct Gilrs { /* private fields */ }
Expand description

Main object responsible of managing gamepads.

In order to get gamepad handle, use gamepad(), or connected_gamepad(). The main difference between these two is that gamepad() will also return handle to gamepad that is currently disconnected. However, both functions will return None if gamepad with given id has never existed.

Event loop

All interesting actions like button was pressed or new controller was connected are represented by struct Event. Use next_event() function to retrieve event from queue.

use gilrs::{Gilrs, Event, EventType, Button};

let mut gilrs = Gilrs::new().unwrap();

// Event loop
loop {
    while let Some(event) = gilrs.next_event() {
        match event {
            Event { id, event: EventType::ButtonPressed(Button::South, _), .. } => {
                println!("Player {}: jump!", id)
            }
            Event { id, event: EventType::Disconnected, .. } => {
                println!("We lost player {}", id)
            }
            _ => (),
        };
    }
}

Cached gamepad state

Gilrs also menage cached gamepad state. Updating state is done automatically, unless it’s disabled by GilrsBuilder::set_update_state(false). However, if you are using custom filters, you still have to update state manually – to do this call update() method.

To access state you can use Gamepad::state() function. Gamepad also implement some state related functions directly, see Gamepad for more.

Counter

Gilrs has additional functionality, referred here as counter. The idea behind it is simple, each time you end iteration of update loop, you call Gilrs::inc() which will increase internal counter by one. When state of one if elements changes, value of counter is saved. When checking state of one of elements you can tell exactly when this event happened. Timestamps are not good solution here because they can tell you when system observed event, not when you processed it. On the other hand, they are good when you want to implement key repeat or software debouncing.

use gilrs::{Gilrs, Button};

let mut gilrs = Gilrs::new().unwrap();
let mut player_one = None;

loop {
    while let Some(ev) = gilrs.next_event() {
        if player_one.is_none() {
            player_one = Some(ev.id);
        }

        // Do other things with event
    }

    if let Some(id) = player_one {
        let gamepad = gilrs.gamepad(id);

        if gamepad.is_pressed(Button::DPadLeft) {
            // go left
        }

        match gamepad.button_data(Button::South) {
            Some(d) if d.is_pressed() && d.counter() == gilrs.counter() => {
                // jump only if button was observed to be pressed in this iteration
            }
            _ => ()
        }
    }

    // Increase counter
    gilrs.inc();
}

Implementations§

source§

impl Gilrs

source

pub fn new() -> Result<Gilrs, Error>

Creates new Gilrs with default settings. See GilrsBuilder for more details.

source

pub fn next_event(&mut self) -> Option<Event>

Returns next pending event. If there is no pending event, None is returned. This function will not block current thread and should be safe to call in async context. Doesn’t block the thread it is run in

source

pub fn next_event_blocking( &mut self, timeout: Option<Duration> ) -> Option<Event>

Same as Gilrs::next_event, but blocks the thread it is run in. Useful for apps that aren’t run inside a loop and just react to the user’s input, like GUI apps.

Platform support

This function is not supported on web and will always panic.

source

pub fn update(&mut self, event: &Event)

Updates internal state according to event.

Please note, that it’s not necessary to call this function unless you modify events by using additional filters and disabled automatic updates when creating Gilrs.

source

pub fn inc(&mut self)

Increases internal counter by one. Counter data is stored with state and can be used to determine when last event happened. You probably want to use this function in your update loop after processing events.

source

pub fn counter(&self) -> u64

Returns counter. Counter data is stored with state and can be used to determine when last event happened.

source

pub fn reset_counter(&mut self)

Sets counter to 0.

source

pub fn gamepad(&self, id: GamepadId) -> Gamepad<'_>

Returns handle to gamepad with given ID. Unlike connected_gamepad(), this function will also return handle to gamepad that is currently disconnected.

use gilrs::{Button, EventType};

loop {
    while let Some(ev) = gilrs.next_event() {
        // unwrap() should never panic because we use id from event
        let is_up_pressed = gilrs.gamepad(ev.id).is_pressed(Button::DPadUp);

        match ev.event {
            EventType::ButtonPressed(Button::South, _) if is_up_pressed => {
                // do something…
            }
            _ => (),
        }
    }
}
source

pub fn connected_gamepad(&self, id: GamepadId) -> Option<Gamepad<'_>>

Returns a reference to connected gamepad or None.

source

pub fn gamepads(&self) -> ConnectedGamepadsIterator<'_>

Returns iterator over all connected gamepads and their ids.

for (id, gamepad) in gilrs.gamepads() {
    assert!(gamepad.is_connected());
    println!("Gamepad with id {} and name {} is connected",
             id, gamepad.name());
}
source

pub fn insert_event(&mut self, ev: Event)

Adds ev at the end of internal event queue. It can later be retrieved with next_event().

source

pub fn set_mapping<'b, O>( &mut self, gamepad_id: usize, mapping: &MappingData, name: O ) -> Result<String, MappingError>where O: Into<Option<&'b str>>,

Sets gamepad’s mapping and returns SDL2 representation of them. Returned mappings may not be compatible with SDL2 - if it is important, use set_mapping_strict().

The name argument can be a string slice with custom gamepad name or None. If None, gamepad name reported by driver will be used.

Errors

This function return error if name contains comma, mapping have axis and button entry for same element (for example Axis::LetfTrigger and Button::LeftTrigger) or gamepad does not have any element with EvCode used in mapping. Button::Unknown and Axis::Unknown are not allowd as keys to mapping – in this case, MappingError::UnknownElement is returned.

Error is also returned if this function is not implemented or gamepad is not connected.

Example
use gilrs::{Mapping, Button};

let mut data = Mapping::new();
// …

// or `match gilrs.set_mapping(0, &data, None) {`
match gilrs.set_mapping(0, &data, "Custom name") {
    Ok(sdl) => println!("SDL2 mapping: {}", sdl),
    Err(e) => println!("Failed to set mapping: {}", e),
};

See also examples/mapping.rs.

source

pub fn set_mapping_strict<'b, O>( &mut self, gamepad_id: usize, mapping: &MappingData, name: O ) -> Result<String, MappingError>where O: Into<Option<&'b str>>,

Similar to set_mapping() but returned string should be compatible with SDL2.

Errors

Returns MappingError::NotSdl2Compatible if mapping have an entry for Button::{C, Z} or Axis::{LeftZ, RightZ}.

Trait Implementations§

source§

impl Debug for Gilrs

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Gilrs> for GamepadContext

source§

fn from(gilrs: Gilrs) -> Self

Converts from a Gilrs custom instance to a GilrsGamepadContext

Auto Trait Implementations§

§

impl RefUnwindSafe for Gilrs

§

impl Send for Gilrs

§

impl !Sync for Gilrs

§

impl Unpin for Gilrs

§

impl UnwindSafe for Gilrs

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

source§

impl<T> Has<T> for T

source§

fn retrieve(&self) -> &T

Method to retrieve the context type.
source§

impl<T> HasMut<T> for T

source§

fn retrieve_mut(&mut self) -> &mut T

Method to retrieve the context type as mutable.
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<F, T> IntoSample<T> for Fwhere T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T, U> ToSample<U> for Twhere U: FromSample<T>,

§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<S, T> Duplex<S> for Twhere T: FromSample<S> + ToSample<S>,