use crate::{
Cancellation, Input, InputBundle, ManageCancellation, ManageInput, Operation, OperationCleanup,
OperationReachability, OperationRequest, OperationResult, OperationSetup, OrBroken,
ReachabilityResult, SingleInputStorage,
};
pub struct OperateCancel<T: 'static + Send + Sync + ToString> {
_ignore: std::marker::PhantomData<fn(T)>,
}
impl<T> OperateCancel<T>
where
T: 'static + Send + Sync + ToString,
{
pub fn new() -> Self {
Self {
_ignore: Default::default(),
}
}
}
impl<T> Operation for OperateCancel<T>
where
T: 'static + Send + Sync + ToString,
{
fn setup(self, OperationSetup { source, world }: OperationSetup) -> OperationResult {
world.entity_mut(source).insert(InputBundle::<T>::new());
Ok(())
}
fn execute(
OperationRequest {
source,
world,
roster,
}: OperationRequest,
) -> OperationResult {
let mut source_mut = world.get_entity_mut(source).or_broken()?;
let Input { session, data } = source_mut.take_input::<T>().or_broken()?;
let cancellation = Cancellation::triggered(source, Some(data.to_string()));
source_mut.emit_cancel(session, cancellation, roster);
Ok(())
}
fn cleanup(mut clean: OperationCleanup) -> OperationResult {
clean.cleanup_inputs::<T>()?;
clean.notify_cleaned()
}
fn is_reachable(mut reachability: OperationReachability) -> ReachabilityResult {
if reachability.has_input::<T>()? {
return Ok(true);
}
SingleInputStorage::is_reachable(&mut reachability)
}
}
pub struct OperateQuietCancel;
impl Operation for OperateQuietCancel {
fn setup(self, OperationSetup { source, world }: OperationSetup) -> OperationResult {
world.entity_mut(source).insert(InputBundle::<()>::new());
Ok(())
}
fn execute(
OperationRequest {
source,
world,
roster,
}: OperationRequest,
) -> OperationResult {
let mut source_mut = world.get_entity_mut(source).or_broken()?;
let Input { session, .. } = source_mut.take_input::<()>().or_broken()?;
let cancellation = Cancellation::triggered(source, None);
source_mut.emit_cancel(session, cancellation, roster);
Ok(())
}
fn cleanup(mut clean: OperationCleanup) -> OperationResult {
clean.cleanup_inputs::<()>()?;
clean.notify_cleaned()
}
fn is_reachable(mut reachability: OperationReachability) -> ReachabilityResult {
if reachability.has_input::<()>()? {
return Ok(true);
}
SingleInputStorage::is_reachable(&mut reachability)
}
}