use std::iter::FusedIterator;
use super::ffi::{self, GameActivityKeyEvent, GameActivityMotionEvent};
use crate::input::{
Axis, Button, ButtonState, EdgeFlags, KeyAction, KeyEventFlags, Keycode, MetaState,
MotionAction, MotionEventFlags, Pointer, PointersIter, Source, ToolType,
};
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum InputEvent<'a> {
MotionEvent(MotionEvent<'a>),
KeyEvent(KeyEvent<'a>),
TextEvent(crate::input::TextInputState),
TextAction(crate::input::TextInputAction),
}
#[derive(Clone, Debug)]
pub struct MotionEvent<'a> {
ga_event: &'a GameActivityMotionEvent,
}
impl<'a> MotionEvent<'a> {
pub(crate) fn new(ga_event: &'a GameActivityMotionEvent) -> Self {
Self { ga_event }
}
#[inline]
pub fn source(&self) -> Source {
let source = self.ga_event.source as u32;
source.into()
}
#[inline]
pub fn device_id(&self) -> i32 {
self.ga_event.deviceId
}
#[inline]
pub fn action(&self) -> MotionAction {
let action = self.ga_event.action as u32 & ndk_sys::AMOTION_EVENT_ACTION_MASK;
action.into()
}
#[inline]
pub fn action_button(&self) -> Button {
let action = self.ga_event.actionButton as u32;
action.into()
}
#[inline]
pub fn pointer_index(&self) -> usize {
let action = self.ga_event.action as u32;
let index = (action & ndk_sys::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
>> ndk_sys::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
index as usize
}
#[inline]
pub fn pointer_count(&self) -> usize {
self.ga_event.pointerCount as usize
}
#[inline]
pub fn pointers(&self) -> PointersIter<'_> {
PointersIter {
inner: PointersIterImpl {
event: self,
next_index: 0,
count: self.pointer_count(),
},
}
}
#[inline]
pub fn pointer_at_index(&self, index: usize) -> Pointer<'_> {
if index >= self.pointer_count() {
panic!("Pointer index {} is out of bounds", index);
}
Pointer {
inner: PointerImpl { event: self, index },
}
}
#[inline]
pub fn meta_state(&self) -> MetaState {
MetaState(self.ga_event.metaState as u32)
}
#[inline]
pub fn button_state(&self) -> ButtonState {
ButtonState(self.ga_event.buttonState as u32)
}
#[inline]
pub fn down_time(&self) -> i64 {
self.ga_event.downTime
}
#[inline]
pub fn edge_flags(&self) -> EdgeFlags {
EdgeFlags(self.ga_event.edgeFlags as u32)
}
#[inline]
pub fn event_time(&self) -> i64 {
self.ga_event.eventTime * 1_000_000 }
#[inline]
pub fn flags(&self) -> MotionEventFlags {
MotionEventFlags(self.ga_event.flags as u32)
}
#[inline]
pub fn x_precision(&self) -> f32 {
self.ga_event.precisionX
}
#[inline]
pub fn y_precision(&self) -> f32 {
self.ga_event.precisionY
}
}
#[derive(Debug)]
pub(crate) struct PointerImpl<'a> {
event: &'a MotionEvent<'a>,
index: usize,
}
impl PointerImpl<'_> {
#[inline]
pub fn pointer_index(&self) -> usize {
self.index
}
#[inline]
pub fn pointer_id(&self) -> i32 {
let pointer = &self.event.ga_event.pointers[self.index];
pointer.id
}
#[inline]
pub fn axis_value(&self, axis: Axis) -> f32 {
let pointer = &self.event.ga_event.pointers[self.index];
let axis: u32 = axis.into();
pointer.axisValues[axis as usize]
}
#[inline]
pub fn raw_x(&self) -> f32 {
let pointer = &self.event.ga_event.pointers[self.index];
pointer.rawX
}
#[inline]
pub fn raw_y(&self) -> f32 {
let pointer = &self.event.ga_event.pointers[self.index];
pointer.rawY
}
#[inline]
pub fn tool_type(&self) -> ToolType {
let pointer = &self.event.ga_event.pointers[self.index];
let tool_type = pointer.toolType as u32;
tool_type.into()
}
pub fn history(&self) -> crate::input::PointerHistoryIter<'_> {
let history_size = self.event.ga_event.historySize as usize;
crate::input::PointerHistoryIter {
inner: PointerHistoryIterImpl {
event: self.event.ga_event,
pointer_index: self.index,
front: 0,
back: history_size,
},
}
}
}
#[derive(Debug)]
pub(crate) struct PointersIterImpl<'a> {
event: &'a MotionEvent<'a>,
next_index: usize,
count: usize,
}
impl<'a> Iterator for PointersIterImpl<'a> {
type Item = Pointer<'a>;
fn next(&mut self) -> Option<Pointer<'a>> {
if self.next_index < self.count {
let ptr = Pointer {
inner: PointerImpl {
event: self.event,
index: self.next_index,
},
};
self.next_index += 1;
Some(ptr)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.count - self.next_index;
(size, Some(size))
}
}
impl ExactSizeIterator for PointersIterImpl<'_> {}
#[derive(Debug)]
pub struct HistoricalPointerImpl<'a> {
event: &'a GameActivityMotionEvent,
pointer_index: usize,
history_index: usize,
}
impl<'a> HistoricalPointerImpl<'a> {
#[inline]
pub fn pointer_index(&self) -> usize {
self.pointer_index
}
#[inline]
pub fn event_time(&self) -> i64 {
unsafe { *self.event.historicalEventTimesNanos.add(self.history_index) }
}
#[inline]
pub fn pointer_id(&self) -> i32 {
let pointer = &self.event.pointers[self.pointer_index];
pointer.id
}
#[inline]
pub fn history_index(&self) -> usize {
self.history_index
}
#[inline]
pub fn axis_value(&self, axis: Axis) -> f32 {
unsafe {
ffi::GameActivityMotionEvent_getHistoricalAxisValue(
self.event,
Into::<u32>::into(axis) as i32,
self.pointer_index as i32,
self.history_index as i32,
)
}
}
}
#[derive(Debug)]
pub struct PointerHistoryIterImpl<'a> {
event: &'a GameActivityMotionEvent,
pointer_index: usize,
front: usize,
back: usize,
}
impl<'a> Iterator for PointerHistoryIterImpl<'a> {
type Item = crate::input::HistoricalPointer<'a>;
fn next(&mut self) -> Option<crate::input::HistoricalPointer<'a>> {
if self.front == self.back {
return None;
}
let history_index = self.front;
self.front += 1;
Some(crate::input::HistoricalPointer {
inner: crate::input::HistoricalPointerImpl {
event: self.event,
history_index,
pointer_index: self.pointer_index,
},
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.back - self.front;
(size, Some(size))
}
}
impl<'a> DoubleEndedIterator for PointerHistoryIterImpl<'a> {
fn next_back(&mut self) -> Option<crate::input::HistoricalPointer<'a>> {
if self.front == self.back {
return None;
}
self.back -= 1;
let history_index = self.back;
Some(crate::input::HistoricalPointer {
inner: crate::input::HistoricalPointerImpl {
event: self.event,
history_index,
pointer_index: self.pointer_index,
},
})
}
}
impl ExactSizeIterator for PointerHistoryIterImpl<'_> {}
impl FusedIterator for PointerHistoryIterImpl<'_> {}
#[derive(Debug, Clone)]
pub struct KeyEvent<'a> {
ga_event: &'a GameActivityKeyEvent,
}
impl<'a> KeyEvent<'a> {
pub(crate) fn new(ga_event: &'a GameActivityKeyEvent) -> Self {
Self { ga_event }
}
#[inline]
pub fn source(&self) -> Source {
let source = self.ga_event.source as u32;
source.into()
}
#[inline]
pub fn device_id(&self) -> i32 {
self.ga_event.deviceId
}
#[inline]
pub fn action(&self) -> KeyAction {
let action = self.ga_event.action as u32;
action.into()
}
#[inline]
pub fn action_button(&self) -> KeyAction {
let action = self.ga_event.action as u32;
action.into()
}
#[inline]
pub fn down_time(&self) -> i64 {
self.ga_event.downTime
}
#[inline]
pub fn event_time(&self) -> i64 {
self.ga_event.eventTime
}
#[inline]
pub fn key_code(&self) -> Keycode {
let keycode = self.ga_event.keyCode as u32;
keycode.into()
}
#[inline]
pub fn repeat_count(&self) -> i32 {
self.ga_event.repeatCount
}
#[inline]
pub fn scan_code(&self) -> i32 {
self.ga_event.scanCode
}
}
impl KeyEvent<'_> {
#[inline]
pub fn flags(&self) -> KeyEventFlags {
KeyEventFlags(self.ga_event.flags as u32)
}
#[inline]
pub fn meta_state(&self) -> MetaState {
MetaState(self.ga_event.metaState as u32)
}
}