1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use ffi; use glib; use glib::object::IsA; use glib::source::{Continue, Priority}; use glib::translate::*; use glib_ffi; use glib_ffi::{gboolean, gpointer}; use std::cell::RefCell; use std::mem::transmute; use RTSPSessionPool; unsafe extern "C" fn trampoline_watch( pool: *mut ffi::GstRTSPSessionPool, func: gpointer, ) -> gboolean { #[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] let func: &RefCell<Box<FnMut(&RTSPSessionPool) -> Continue + Send + 'static>> = transmute(func); (&mut *func.borrow_mut())(&from_glib_borrow(pool)).to_glib() } unsafe extern "C" fn destroy_closure_watch(ptr: gpointer) { Box::<RefCell<Box<FnMut(&RTSPSessionPool) -> Continue + Send + 'static>>>::from_raw( ptr as *mut _, ); } fn into_raw_watch<F: FnMut(&RTSPSessionPool) -> Continue + Send + 'static>(func: F) -> gpointer { #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] let func: Box<RefCell<Box<FnMut(&RTSPSessionPool) -> Continue + Send + 'static>>> = Box::new(RefCell::new(Box::new(func))); Box::into_raw(func) as gpointer } pub trait RTSPSessionPoolExtManual { fn create_watch<'a, N: Into<Option<&'a str>>, F>( &self, name: N, priority: Priority, func: F, ) -> glib::Source where F: FnMut(&RTSPSessionPool) -> Continue + Send + 'static; } impl<O: IsA<RTSPSessionPool>> RTSPSessionPoolExtManual for O { fn create_watch<'a, N: Into<Option<&'a str>>, F>( &self, name: N, priority: Priority, func: F, ) -> glib::Source where F: FnMut(&RTSPSessionPool) -> Continue + Send + 'static, { skip_assert_initialized!(); unsafe { let source = ffi::gst_rtsp_session_pool_create_watch(self.to_glib_none().0); let trampoline = trampoline_watch as gpointer; glib_ffi::g_source_set_callback( source, Some(transmute(trampoline)), into_raw_watch(func), Some(destroy_closure_watch), ); glib_ffi::g_source_set_priority(source, priority.to_glib()); let name = name.into(); if let Some(name) = name { glib_ffi::g_source_set_name(source, name.to_glib_none().0); } from_glib_full(source) } } }