use core::future::Future;
use core::pin::pin;
use core::task::{Context, Poll};
use crate::{CurrentTask, Duration, Task};
mod waker {
use core::task::{RawWaker, RawWakerVTable, Waker};
use veecle_freertos_sys::bindings::TaskHandle_t;
use crate::{Task, TaskNotification};
static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop);
unsafe fn clone(handle: *const ()) -> RawWaker {
RawWaker::new(handle, &VTABLE)
}
unsafe fn wake(handle: *const ()) {
let handle: TaskHandle_t = handle.cast_mut().cast();
let task = unsafe { Task::from_raw_handle(handle) };
task.notify(TaskNotification::Increment);
}
fn drop(_handle: *const ()) {
}
pub fn new(task: Task) -> Waker {
let handle: TaskHandle_t = task.raw_handle();
Task::assert_no_task_deletion();
unsafe { Waker::new(handle.cast(), &VTABLE) }
}
}
pub fn block_on_future<T>(future: impl Future<Output = T>) -> T {
let task = Task::current().expect(
"Could not find the task of the current execution context. Ensure that the method is called inside a \
FreeRTOS task.",
);
let waker = waker::new(task);
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
if let Poll::Ready(value) = future.as_mut().poll(&mut context) {
break value;
}
CurrentTask::take_notification(true, Duration::max());
}
}