use super::*;
#[allow(unused_variables)]
pub trait Action: downcast_rs::Downcast + Send + Sync + 'static {
fn is_finished(&self, agent: Entity, world: &World) -> bool;
fn on_start(&mut self, agent: Entity, world: &mut World) -> bool;
fn on_stop(&mut self, agent: Option<Entity>, world: &mut World, reason: StopReason);
fn on_add(&mut self, agent: Entity, world: &mut World) {}
fn on_remove(&mut self, agent: Option<Entity>, world: &mut World) {}
fn on_drop(self: Box<Self>, agent: Option<Entity>, world: &mut World, reason: DropReason) {}
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
}
downcast_rs::impl_downcast!(Action);
impl std::fmt::Debug for BoxedAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.type_name())
}
}
impl<OnStart> Action for OnStart
where
OnStart: FnMut(Entity, &mut World) -> bool + Send + Sync + 'static,
{
fn is_finished(&self, _agent: Entity, _world: &World) -> bool {
true
}
fn on_start(&mut self, agent: Entity, world: &mut World) -> bool {
(self)(agent, world)
}
fn on_stop(&mut self, _agent: Option<Entity>, _world: &mut World, _reason: StopReason) {}
}
pub trait ActionsProxy {
fn actions(&mut self, agent: Entity) -> impl ManageActions;
}
pub trait ManageActions {
fn config(&mut self, config: AddConfig) -> &mut Self;
fn start(&mut self, start: bool) -> &mut Self;
fn order(&mut self, order: AddOrder) -> &mut Self;
fn add(&mut self, actions: impl IntoBoxedActions) -> &mut Self;
fn execute(&mut self) -> &mut Self;
fn next(&mut self) -> &mut Self;
fn cancel(&mut self) -> &mut Self;
fn pause(&mut self) -> &mut Self;
fn skip(&mut self, n: usize) -> &mut Self;
fn clear(&mut self) -> &mut Self;
}
pub trait IntoBoxedAction {
fn into_boxed_action(self) -> BoxedAction;
}
impl<T: Action> IntoBoxedAction for T {
fn into_boxed_action(self) -> BoxedAction {
Box::new(self)
}
}
impl IntoBoxedAction for BoxedAction {
fn into_boxed_action(self) -> BoxedAction {
self
}
}
pub trait IntoBoxedActions {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static;
}
impl<T: Action> IntoBoxedActions for T {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
[self.into_boxed_action()].into_iter()
}
}
macro_rules! impl_action_tuple {
($($T:ident),+) => {
impl<$($T:Action),+> IntoBoxedActions for ($($T,)+) {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
#[allow(non_snake_case)]
let ($($T,)+) = self;
[$( $T.into_boxed_action() ),+].into_iter()
}
}
};
}
variadics_please::all_tuples!(impl_action_tuple, 1, 15, T);
impl IntoBoxedActions for BoxedAction {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
[self].into_iter()
}
}
impl<const N: usize> IntoBoxedActions for [BoxedAction; N] {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
self.into_iter()
}
}
impl IntoBoxedActions for Vec<BoxedAction> {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
self.into_iter()
}
}
impl IntoBoxedActions for VecDeque<BoxedAction> {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
self.into_iter()
}
}
impl IntoBoxedActions for std::collections::LinkedList<BoxedAction> {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
self.into_iter()
}
}
impl IntoBoxedActions for std::collections::BinaryHeap<BoxedAction> {
fn into_boxed_actions(
self,
) -> impl DoubleEndedIterator<Item = BoxedAction> + ExactSizeIterator + Send + Debug + 'static
{
self.into_iter()
}
}