use std::{
ops::Deref,
sync::Arc,
time::Duration,
};
use super::{
ConditionWaiter,
NotificationWaiter,
Notifier,
ParkingLotMonitor,
ParkingLotMonitorGuard,
TimeoutConditionWaiter,
TimeoutNotificationWaiter,
WaitTimeoutResult,
WaitTimeoutStatus,
};
pub struct ArcParkingLotMonitor<T> {
inner: Arc<ParkingLotMonitor<T>>,
}
impl<T> ArcParkingLotMonitor<T> {
#[inline]
pub fn new(state: T) -> Self {
Self {
inner: Arc::new(ParkingLotMonitor::new(state)),
}
}
#[inline]
pub fn lock(&self) -> ParkingLotMonitorGuard<'_, T> {
self.inner.lock()
}
#[inline]
pub fn read<R, F>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
self.inner.read(f)
}
#[inline]
pub fn write<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.write(f)
}
#[inline]
pub fn write_notify_one<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.write_notify_one(f)
}
#[inline]
pub fn write_notify_all<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
self.inner.write_notify_all(f)
}
#[inline]
pub fn wait(&self) {
self.inner.wait();
}
#[inline]
pub fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
self.inner.wait_for(timeout)
}
#[inline]
pub fn wait_while<R, P, F>(&self, waiting: P, f: F) -> R
where
P: FnMut(&T) -> bool,
F: FnOnce(&mut T) -> R,
{
self.inner.wait_while(waiting, f)
}
#[inline]
pub fn wait_until<R, P, F>(&self, ready: P, f: F) -> R
where
P: FnMut(&T) -> bool,
F: FnOnce(&mut T) -> R,
{
self.inner.wait_until(ready, f)
}
#[inline]
pub fn wait_while_for<R, P, F>(
&self,
timeout: Duration,
waiting: P,
f: F,
) -> WaitTimeoutResult<R>
where
P: FnMut(&T) -> bool,
F: FnOnce(&mut T) -> R,
{
self.inner.wait_while_for(timeout, waiting, f)
}
#[inline]
pub fn wait_until_for<R, P, F>(&self, timeout: Duration, ready: P, f: F) -> WaitTimeoutResult<R>
where
P: FnMut(&T) -> bool,
F: FnOnce(&mut T) -> R,
{
self.inner.wait_until_for(timeout, ready, f)
}
#[inline]
pub fn notify_one(&self) {
self.inner.notify_one();
}
#[inline]
pub fn notify_all(&self) {
self.inner.notify_all();
}
}
impl<T> AsRef<ParkingLotMonitor<T>> for ArcParkingLotMonitor<T> {
#[inline]
fn as_ref(&self) -> &ParkingLotMonitor<T> {
self.inner.as_ref()
}
}
impl<T> Notifier for ArcParkingLotMonitor<T> {
#[inline]
fn notify_one(&self) {
Self::notify_one(self);
}
#[inline]
fn notify_all(&self) {
Self::notify_all(self);
}
}
impl<T> NotificationWaiter for ArcParkingLotMonitor<T> {
#[inline]
fn wait(&self) {
Self::wait(self);
}
}
impl<T> TimeoutNotificationWaiter for ArcParkingLotMonitor<T> {
#[inline]
fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
Self::wait_for(self, timeout)
}
}
impl<T> ConditionWaiter for ArcParkingLotMonitor<T> {
type State = T;
#[inline]
fn wait_until<R, P, F>(&self, predicate: P, action: F) -> R
where
P: FnMut(&Self::State) -> bool,
F: FnOnce(&mut Self::State) -> R,
{
Self::wait_until(self, predicate, action)
}
#[inline]
fn wait_while<R, P, F>(&self, predicate: P, action: F) -> R
where
P: FnMut(&Self::State) -> bool,
F: FnOnce(&mut Self::State) -> R,
{
Self::wait_while(self, predicate, action)
}
}
impl<T> TimeoutConditionWaiter for ArcParkingLotMonitor<T> {
#[inline]
fn wait_until_for<R, P, F>(
&self,
timeout: Duration,
predicate: P,
action: F,
) -> WaitTimeoutResult<R>
where
P: FnMut(&Self::State) -> bool,
F: FnOnce(&mut Self::State) -> R,
{
Self::wait_until_for(self, timeout, predicate, action)
}
#[inline]
fn wait_while_for<R, P, F>(
&self,
timeout: Duration,
predicate: P,
action: F,
) -> WaitTimeoutResult<R>
where
P: FnMut(&Self::State) -> bool,
F: FnOnce(&mut Self::State) -> R,
{
Self::wait_while_for(self, timeout, predicate, action)
}
}
impl<T> Deref for ArcParkingLotMonitor<T> {
type Target = ParkingLotMonitor<T>;
#[inline]
fn deref(&self) -> &Self::Target {
self.inner.as_ref()
}
}
impl<T> From<T> for ArcParkingLotMonitor<T> {
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T: Default> Default for ArcParkingLotMonitor<T> {
#[inline]
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> Clone for ArcParkingLotMonitor<T> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}