use std::{any::Any, any::TypeId, rc::Rc};
use crate::{GestureAction, GestureDecision, PointerEvent, RawPointerEvent};
pub trait GestureRecognizer: Any {
fn observe(&mut self, event: PointerEvent) -> GestureDecision;
fn observe_raw(&mut self, event: RawPointerEvent) -> GestureDecision {
self.observe(event.legacy())
}
fn dispatch(&mut self, action: GestureAction);
fn cancel(&mut self) {}
fn dispose(&mut self) {}
fn as_any_mut(&mut self) -> &mut dyn Any;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
#[error("gesture recognizer factory type mismatch (expected {expected:?}, got {actual:?})")]
pub struct GestureRecognizerFactoryError {
pub expected: TypeId,
pub actual: TypeId,
}
pub trait GestureRecognizerFactory {
fn type_id(&self) -> TypeId;
fn create(&self) -> Box<dyn GestureRecognizer>;
fn initialize(
&self,
recognizer: &mut dyn GestureRecognizer,
) -> Result<(), GestureRecognizerFactoryError>;
}
pub struct GestureRecognizerFactoryWithHandlers<T: GestureRecognizer + 'static> {
constructor: Rc<dyn Fn() -> T>,
initializer: Rc<dyn Fn(&mut T)>,
}
impl<T: GestureRecognizer + 'static> Clone for GestureRecognizerFactoryWithHandlers<T> {
fn clone(&self) -> Self {
Self {
constructor: self.constructor.clone(),
initializer: self.initializer.clone(),
}
}
}
impl<T: GestureRecognizer + 'static> GestureRecognizerFactoryWithHandlers<T> {
#[must_use]
pub fn new(
constructor: impl Fn() -> T + 'static,
initializer: impl Fn(&mut T) + 'static,
) -> Self {
Self {
constructor: Rc::new(constructor),
initializer: Rc::new(initializer),
}
}
#[must_use]
pub fn with_initializer(initializer: impl Fn(&mut T) + 'static) -> Self
where
T: Default,
{
Self::new(T::default, initializer)
}
}
impl<T: GestureRecognizer + 'static> GestureRecognizerFactory
for GestureRecognizerFactoryWithHandlers<T>
{
fn type_id(&self) -> TypeId {
TypeId::of::<T>()
}
fn create(&self) -> Box<dyn GestureRecognizer> {
Box::new((self.constructor)())
}
fn initialize(
&self,
recognizer: &mut dyn GestureRecognizer,
) -> Result<(), GestureRecognizerFactoryError> {
let expected = TypeId::of::<T>();
if !recognizer.as_any_mut().is::<T>() {
return Err(GestureRecognizerFactoryError {
expected,
actual: TypeId::of::<dyn GestureRecognizer>(),
});
}
let recognizer = recognizer
.as_any_mut()
.downcast_mut::<T>()
.expect("recognizer type checked immediately above");
(self.initializer)(recognizer);
Ok(())
}
}
#[derive(Clone)]
pub struct ErasedGestureRecognizerFactory(Rc<dyn GestureRecognizerFactory>);
impl ErasedGestureRecognizerFactory {
#[must_use]
pub fn new(factory: impl GestureRecognizerFactory + 'static) -> Self {
Self(Rc::new(factory))
}
#[must_use]
pub fn type_id(&self) -> TypeId {
self.0.type_id()
}
pub fn create(&self) -> Box<dyn GestureRecognizer> {
self.0.create()
}
pub fn initialize(
&self,
recognizer: &mut dyn GestureRecognizer,
) -> Result<(), GestureRecognizerFactoryError> {
self.0.initialize(recognizer)
}
#[must_use]
pub fn ptr_eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl<T: GestureRecognizer + 'static> From<GestureRecognizerFactoryWithHandlers<T>>
for ErasedGestureRecognizerFactory
{
fn from(factory: GestureRecognizerFactoryWithHandlers<T>) -> Self {
Self::new(factory)
}
}
impl From<Rc<dyn GestureRecognizerFactory>> for ErasedGestureRecognizerFactory {
fn from(factory: Rc<dyn GestureRecognizerFactory>) -> Self {
Self(factory)
}
}
impl From<Box<dyn GestureRecognizerFactory>> for ErasedGestureRecognizerFactory {
fn from(factory: Box<dyn GestureRecognizerFactory>) -> Self {
Self(Rc::from(factory))
}
}