use bevy::{ecs::component::ComponentId, prelude::*};
use serde::{Serialize, de::DeserializeOwned};
use crate::{
prelude::*,
shared::replication::registry::{FnsId, ReplicationRegistry, receive_fns::MutWrite},
};
#[derive(Clone, Copy, Debug)]
pub struct ComponentRule {
pub id: ComponentId,
pub fns_id: FnsId,
pub mode: ReplicationMode,
}
impl ComponentRule {
pub fn new(id: ComponentId, fns_id: FnsId) -> Self {
Self {
id,
fns_id,
mode: Default::default(),
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum ReplicationMode {
#[default]
OnChange,
Once,
}
pub trait IntoComponentRule {
fn into_rule(self, world: &mut World, registry: &mut ReplicationRegistry) -> ComponentRule;
}
impl<C: Component<Mutability: MutWrite<C>>> IntoComponentRule for RuleFns<C> {
fn into_rule(self, world: &mut World, registry: &mut ReplicationRegistry) -> ComponentRule {
let (id, fns_id) = registry.register_rule_fns(world, self);
ComponentRule::new(id, fns_id)
}
}
impl<C: Component<Mutability: MutWrite<C>>> IntoComponentRule for (RuleFns<C>, ReplicationMode) {
fn into_rule(self, world: &mut World, registry: &mut ReplicationRegistry) -> ComponentRule {
let (rule_fns, mode) = self;
let (id, fns_id) = registry.register_rule_fns(world, rule_fns);
ComponentRule { id, fns_id, mode }
}
}
pub trait IntoComponentRules {
const DEFAULT_PRIORITY: usize;
fn into_rules(
self,
world: &mut World,
registry: &mut ReplicationRegistry,
) -> Vec<ComponentRule>;
}
impl<C: IntoComponentRule> IntoComponentRules for C {
const DEFAULT_PRIORITY: usize = 1;
fn into_rules(
self,
world: &mut World,
registry: &mut ReplicationRegistry,
) -> Vec<ComponentRule> {
vec![self.into_rule(world, registry)]
}
}
macro_rules! impl_into_component_rules {
($(($n:tt, $R:ident)),*) => {
impl<$($R: IntoComponentRule),*> IntoComponentRules for ($($R,)*) {
const DEFAULT_PRIORITY: usize = 0 $(+ { let _ = $n; 1 })*;
fn into_rules(
self,
world: &mut World,
registry: &mut ReplicationRegistry,
) -> Vec<ComponentRule> {
vec![
$(
self.$n.into_rule(world, registry),
)*
]
}
}
}
}
variadics_please::all_tuples_enumerated!(impl_into_component_rules, 1, 15, R);
pub trait BundleRules {
const DEFAULT_PRIORITY: usize;
fn component_rules(world: &mut World, registry: &mut ReplicationRegistry)
-> Vec<ComponentRule>;
}
macro_rules! impl_into_bundle_rules {
($N:expr, $($C:ident),*) => {
impl<$($C: Component<Mutability: MutWrite<$C>> + Serialize + DeserializeOwned),*> BundleRules for ($($C,)*) {
const DEFAULT_PRIORITY: usize = $N;
fn component_rules(world: &mut World, registry: &mut ReplicationRegistry) -> Vec<ComponentRule> {
vec![
$(
{
let (id, fns_id) = registry.register_rule_fns(world, RuleFns::<$C>::default());
ComponentRule {
id,
fns_id,
mode: Default::default(),
}
},
)*
]
}
}
}
}
variadics_please::all_tuples_with_size!(impl_into_bundle_rules, 1, 15, C);