use crate::plugin::TimelineSyncPlugin;
use crate::prelude::InputTimeline;
use crate::prelude::client::RemoteTimeline;
use crate::timeline::input::Input;
use crate::timeline::remote;
use crate::timeline::sync::SyncedTimelinePlugin;
use bevy_app::{App, First, Last, Plugin, PreUpdate};
use bevy_ecs::prelude::*;
use lightyear_connection::client::Client;
use lightyear_core::prelude::{LocalTimeline, NetworkTimeline, NetworkTimelinePlugin};
use lightyear_core::time::TickDelta;
use lightyear_core::timeline::SyncEvent;
use tracing::info;
pub struct ClientPlugin;
impl ClientPlugin {
pub fn update_local_timeline(
trigger: On<SyncEvent<Input>>,
mut query: Query<&mut LocalTimeline>,
) {
if let Ok(mut timeline) = query.get_mut(trigger.entity) {
info!(
"TickDelta: {:?} applied to local timeline",
trigger.tick_delta
);
timeline.apply_delta(TickDelta::from_i16(trigger.tick_delta));
}
}
}
impl Plugin for ClientPlugin {
fn build(&self, app: &mut App) {
if !app.is_plugin_added::<TimelineSyncPlugin>() {
app.add_plugins(TimelineSyncPlugin);
}
app.register_required_components::<Client, InputTimeline>();
app.register_required_components::<Client, RemoteTimeline>();
app.add_observer(Input::recompute_input_delay);
app.add_systems(First, Input::recompute_input_delay_on_config_update);
app.add_plugins(SyncedTimelinePlugin::<InputTimeline, RemoteTimeline, true>::default());
app.add_systems(PreUpdate, InputTimeline::advance_timeline);
app.add_plugins(NetworkTimelinePlugin::<RemoteTimeline>::default());
app.add_observer(RemoteTimeline::handle_connect);
app.add_observer(remote::update_remote_timeline);
app.add_systems(PreUpdate, remote::advance_remote_timeline);
app.add_systems(Last, remote::reset_received_packet_remote_timeline);
}
}
#[cfg(test)]
mod tests {
use super::*;
use bevy_time::{TimePlugin, TimeUpdateStrategy};
use core::time::Duration;
use lightyear_core::prelude::Tick;
use lightyear_core::tick::TickDuration;
use lightyear_core::time::{Instant, Overstep, TickInstant};
use test_log::test;
#[test]
#[ignore = "Broken on main"]
fn test_advance_remote() {
let mut app = App::new();
let now = Instant::now();
app.world_mut()
.insert_resource(TimeUpdateStrategy::ManualDuration(Duration::from_millis(
10,
)));
app.world_mut()
.insert_resource(TickDuration(Duration::from_millis(10)));
app.add_plugins((TimePlugin, ClientPlugin));
app.update();
let e = app.world_mut().spawn(RemoteTimeline::default()).id();
assert_eq!(
app.world().get::<RemoteTimeline>(e).unwrap().now,
TickInstant {
tick: Tick(0),
overstep: Overstep::new(0.0),
}
);
app.update();
assert_eq!(
app.world().get::<RemoteTimeline>(e).unwrap().now,
TickInstant {
tick: Tick(1),
overstep: Overstep::new(0.0),
}
);
}
}