use std;
use capi;
use std::os::raw::c_void;
use std::rc::Rc;
use libc::timeval;
use super::events::io::*;
use super::events::timer::*;
use super::events::deferred::*;
use timeval::Timeval;
pub use capi::pa_mainloop_api as ApiInternal;
pub trait MainloopInternalType {}
pub trait MainloopInnerType {
type I: MainloopInternalType;
fn get_ptr(&self) -> *mut Self::I;
fn get_api(&self) -> &mut MainloopApi;
}
pub struct MainloopInner<T>
where T: MainloopInternalType
{
pub ptr: *mut T,
pub api: *mut MainloopApi,
pub dropfn: fn(&mut MainloopInner<T>),
}
impl<T> Drop for MainloopInner<T>
where T: MainloopInternalType
{
fn drop(&mut self) {
(self.dropfn)(self);
}
}
impl<T> MainloopInnerType for MainloopInner<T>
where T: MainloopInternalType
{
type I = T;
fn get_ptr(&self) -> *mut T {
self.ptr
}
fn get_api(&self) -> &mut MainloopApi {
assert!(!self.api.is_null());
unsafe { &mut *self.api }
}
}
pub trait Mainloop {
type MI: MainloopInnerType;
fn inner(&self) -> Rc<Self::MI>;
fn new_io_event(&mut self, fd: i32, events: IoEventFlagSet, cb: (IoEventCb, *mut c_void)
) -> Option<IoEvent<Self::MI>>
{
let fn_ptr = self.inner().get_api().io_new.unwrap();
let ptr = fn_ptr(self.inner().get_api(), fd, events, Some(cb.0), cb.1);
if ptr.is_null() {
return None;
}
Some(IoEvent::<Self::MI>::from_raw(ptr, self.inner().clone()))
}
fn new_timer_event(&mut self, tv: &Timeval, cb: (TimeEventCb, *mut c_void)
) -> Option<TimeEvent<Self::MI>>
{
let fn_ptr = self.inner().get_api().time_new.unwrap();
let ptr = fn_ptr(self.inner().get_api(), &tv.0, Some(cb.0), cb.1);
if ptr.is_null() {
return None;
}
Some(TimeEvent::<Self::MI>::from_raw(ptr, self.inner().clone()))
}
fn new_deferred_event(&mut self, cb: (DeferEventCb, *mut c_void)
) -> Option<DeferEvent<Self::MI>>
{
let fn_ptr = self.inner().get_api().defer_new.unwrap();
let ptr = fn_ptr(self.inner().get_api(), Some(cb.0), cb.1);
if ptr.is_null() {
return None;
}
Some(DeferEvent::<Self::MI>::from_raw(ptr, self.inner().clone()))
}
fn set_api_userdata(&mut self, userdata: *mut c_void) {
self.inner().get_api().userdata = userdata;
}
fn get_api_userdata(&self) -> *mut c_void {
self.inner().get_api().userdata
}
fn quit(&mut self, retval: ::def::Retval) {
let fn_ptr = self.inner().get_api().quit.unwrap();
fn_ptr(self.inner().get_api(), retval.0);
}
}
#[repr(C)]
pub struct MainloopApi {
pub userdata: *mut c_void,
pub io_new: Option<extern "C" fn(a: *mut MainloopApi, fd: i32, events: IoEventFlagSet,
cb: Option<IoEventCb>, userdata: *mut c_void) -> *mut IoEventInternal>,
pub io_enable: Option<extern "C" fn(e: *mut IoEventInternal, events: IoEventFlagSet)>,
pub io_free: Option<extern "C" fn(e: *mut IoEventInternal)>,
pub io_set_destroy: Option<extern "C" fn(e: *mut IoEventInternal, cb: Option<IoEventDestroyCb>)>,
pub time_new: Option<extern "C" fn(a: *mut MainloopApi, tv: *const timeval,
cb: Option<TimeEventCb>, userdata: *mut c_void) -> *mut TimeEventInternal>,
pub time_restart: Option<extern "C" fn(e: *mut TimeEventInternal, tv: *const timeval)>,
pub time_free: Option<extern "C" fn(e: *mut TimeEventInternal)>,
pub time_set_destroy: Option<extern "C" fn(e: *mut TimeEventInternal,
cb: Option<TimeEventDestroyCb>)>,
pub defer_new: Option<extern "C" fn(a: *mut MainloopApi, cb: Option<DeferEventCb>,
userdata: *mut c_void) -> *mut DeferEventInternal>,
pub defer_enable: Option<extern "C" fn(e: *mut DeferEventInternal, b: i32)>,
pub defer_free: Option<extern "C" fn(e: *mut DeferEventInternal)>,
pub defer_set_destroy: Option<extern "C" fn(e: *mut DeferEventInternal,
cb: Option<DeferEventDestroyCb>)>,
pub quit: Option<extern "C" fn(a: *mut MainloopApi, retval: ::def::RetvalActual)>,
}
pub type MainloopApiOnceCallback = extern "C" fn(m: *mut ApiInternal,
userdata: *mut c_void);
impl MainloopApi {
pub fn mainloop_api_once(&mut self, cb: (MainloopApiOnceCallback, *mut c_void)) {
unsafe { capi::pa_mainloop_api_once(std::mem::transmute(self), Some(cb.0), cb.1) };
}
}