use std::ops::{Add, Mul};
use bevy::prelude::{Added, Commands, Component, Entity, Query, ResMut};
use tracing::info;
pub use interpolate::InterpolateStatus;
pub use interpolation_history::ConfirmedHistory;
pub use plugin::{add_interpolation_systems, add_lerp_systems};
use crate::client::components::{Confirmed, SyncComponent};
use crate::client::interpolation::despawn::InterpolationMapping;
use crate::shared::replication::components::ShouldBeInterpolated;
mod despawn;
mod interpolate;
pub mod interpolation_history;
pub mod plugin;
pub trait InterpolatedComponent:
SyncComponent + Mul<f32, Output = Self> + Add<Self, Output = Self> + Sized
{
fn lerp_mode() -> LerpMode<Self>;
fn lerp(start: Self, other: Self, t: f32) -> Self {
match Self::lerp_mode() {
LerpMode::Linear => start * (1.0 - t) + other * t,
LerpMode::Custom(lerp) => lerp(start, other, t),
}
}
}
#[derive(Debug)]
pub enum LerpMode<C: InterpolatedComponent> {
Linear,
Custom(fn(C, C, f32) -> C),
}
#[derive(Component, Debug)]
pub struct Interpolated {
pub confirmed_entity: Entity,
}
pub fn spawn_interpolated_entity(
mut commands: Commands,
mut mapping: ResMut<InterpolationMapping>,
mut confirmed_entities: Query<(Entity, Option<&mut Confirmed>), Added<ShouldBeInterpolated>>,
) {
for (confirmed_entity, confirmed) in confirmed_entities.iter_mut() {
let interpolated_entity_mut = commands.spawn(Interpolated { confirmed_entity });
let interpolated = interpolated_entity_mut.id();
let mut confirmed_entity_mut = commands.get_entity(confirmed_entity).unwrap();
mapping
.confirmed_to_interpolated
.insert(confirmed_entity, interpolated);
if let Some(mut confirmed) = confirmed {
confirmed.interpolated = Some(interpolated);
} else {
confirmed_entity_mut.insert(Confirmed {
interpolated: Some(interpolated),
predicted: None,
});
}
info!(
"Spawn interpolated entity {:?} for confirmed: {:?}",
interpolated, confirmed_entity
);
#[cfg(feature = "metrics")]
{
metrics::increment_counter!("spawn_interpolated_entity");
}
}
}