diff --git a/src/sdl2/event.rs b/src/sdl2/event.rs index 09ddb782..9cddd982 100644 --- a/src/sdl2/event.rs +++ b/src/sdl2/event.rs @@ -28,6 +28,7 @@ use crate::mouse; use crate::mouse::{MouseButton, MouseState, MouseWheelDirection}; use crate::sys; +use crate::sys::SDL_EventFilter; use crate::sys::SDL_EventType; struct CustomEventTypeMaps { @@ -231,6 +232,13 @@ impl crate::EventSubsystem { pub fn event_sender(&self) -> EventSender { EventSender { _priv: () } } + + pub fn add_event_watch<'a, F: FnMut(Event) -> () + 'a>( + &self, + callback: F, + ) -> EventWatch<'a, F> { + EventWatch::add(callback) + } } /// Types of events that can be delivered. @@ -2894,3 +2902,40 @@ impl EventSender { Ok(()) } } + +pub struct EventWatch<'a, F: FnMut(Event) -> () + 'a>(Box, PhantomData<&'a F>); + +impl<'a, F: FnMut(Event) -> () + 'a> EventWatch<'a, F> { + pub fn add(f: F) -> EventWatch<'a, F> { + let f = Box::new(f); + let mut watch = EventWatch(f, PhantomData); + unsafe { sys::SDL_AddEventWatch(watch.filter(), watch.callback()) }; + println!("Added"); + watch + } + + fn filter(&self) -> SDL_EventFilter { + Some(event_callback_marshall:: as _) + } + + fn callback(&mut self) -> *mut c_void { + &mut *self.0 as *mut _ as *mut c_void + } +} + +impl<'a, F: FnMut(Event) -> () + 'a> Drop for EventWatch<'a, F> { + fn drop(&mut self) { + unsafe { sys::SDL_DelEventWatch(self.filter(), self.callback()) }; + println!("Deleted"); + } +} + +extern "C" fn event_callback_marshall ()>( + user_data: *mut c_void, + event: *mut sdl2_sys::SDL_Event, +) -> i32 { + let f: &mut F = unsafe { &mut *(user_data as *mut _) }; + let event = Event::from_ll(unsafe { *event }); + f(event); + 0 +}