use std::convert::TryInto;
use crate::ffi::{clWaitForEvents, cl_event};
use crate::{
build_output,
ClEvent,
EventPtr, Output,
};
pub unsafe fn cl_wait_for_events<'a>(wl: &'a [cl_event]) -> Output<()> {
build_output((), clWaitForEvents(wl.waitlist_len(), wl.waitlist_ptr()))
}
pub unsafe trait Waitlist: Sized {
unsafe fn fill_waitlist(&self, wl: &mut Vec<cl_event>);
unsafe fn new_waitlist(&self) -> Vec<cl_event>;
unsafe fn wait(self) -> Output<()> {
let mut waitlist = Vec::new();
self.fill_waitlist(&mut waitlist);
cl_wait_for_events(&waitlist[..])
}
}
pub unsafe trait WaitlistSizeAndPtr<'a>: Sized {
unsafe fn waitlist_len(&self) -> u32;
unsafe fn waitlist_ptr(&self) -> *const cl_event;
}
unsafe impl<'a> WaitlistSizeAndPtr<'a> for &'a [cl_event] {
unsafe fn waitlist_len(&self) -> u32 {
self.len().try_into().unwrap()
}
unsafe fn waitlist_ptr(&self) -> *const cl_event {
match self.len() {
0 => std::ptr::null() as *const cl_event,
_ => *self as *const _ as *const cl_event,
}
}
}
unsafe impl Waitlist for &[cl_event] {
unsafe fn fill_waitlist(&self, wait_list: &mut Vec<cl_event>) {
wait_list.extend_from_slice(self);
}
unsafe fn new_waitlist(&self) -> Vec<cl_event> {
self.to_vec()
}
}
unsafe impl Waitlist for &[ClEvent] {
unsafe fn fill_waitlist(&self, wait_list: &mut Vec<cl_event>) {
let waitlist = self.new_waitlist();
wait_list.extend(waitlist);
}
unsafe fn new_waitlist(&self) -> Vec<cl_event> {
self.iter().map(|evt| evt.event_ptr()).collect()
}
}
unsafe impl Waitlist for &ClEvent {
unsafe fn fill_waitlist(&self, wait_list: &mut Vec<cl_event>) {
wait_list.push(self.event_ptr());
}
unsafe fn new_waitlist(&self) -> Vec<cl_event> {
vec![self.event_ptr()]
}
}
unsafe impl<W: Waitlist> Waitlist for Option<W> {
unsafe fn fill_waitlist(&self, wait_list: &mut Vec<cl_event>) {
match self {
None => (),
Some(event) => event.fill_waitlist(wait_list),
}
}
unsafe fn new_waitlist(&self) -> Vec<cl_event> {
match self {
None => vec![],
Some(event) => event.new_waitlist(),
}
}
}