From 776e59f5ded1d61a1019d1360887a2d64f250d9a Mon Sep 17 00:00:00 2001 From: cBournhonesque Date: Sun, 19 Jan 2025 17:29:56 -0500 Subject: [PATCH 1/2] make history buffer public (for lag compensation) --- .../src/client/prediction/predicted_history.rs | 7 ++++--- lightyear/src/lib.rs | 1 + .../history.rs => utils/history_buffer.rs} | 16 ++++++++-------- lightyear/src/utils/mod.rs | 1 + 4 files changed, 14 insertions(+), 11 deletions(-) rename lightyear/src/{client/prediction/history.rs => utils/history_buffer.rs} (94%) diff --git a/lightyear/src/client/prediction/predicted_history.rs b/lightyear/src/client/prediction/predicted_history.rs index 736676cd9..175a4eb28 100644 --- a/lightyear/src/client/prediction/predicted_history.rs +++ b/lightyear/src/client/prediction/predicted_history.rs @@ -9,11 +9,12 @@ use bevy::prelude::{ use tracing::{debug, trace}; use crate::client::components::{ComponentSyncMode, Confirmed, SyncComponent}; -use crate::client::prediction::history::HistoryBuffer; use crate::client::prediction::resource::PredictionManager; use crate::client::prediction::rollback::Rollback; use crate::client::prediction::Predicted; -use crate::prelude::{ComponentRegistry, PreSpawnedPlayerObject, ShouldBePredicted, TickManager}; +use crate::prelude::{ + ComponentRegistry, HistoryBuffer, PreSpawnedPlayerObject, ShouldBePredicted, TickManager, +}; use crate::shared::tick_manager::{Tick, TickEvent}; pub(crate) type PredictionHistory = HistoryBuffer; @@ -299,8 +300,8 @@ pub(crate) fn apply_confirmed_update( #[cfg(test)] mod tests { use super::*; - use crate::client::prediction::history::HistoryState; use crate::prelude::client::RollbackState; + use crate::prelude::HistoryState; use crate::tests::protocol::*; use crate::tests::stepper::BevyStepper; use bevy::ecs::system::RunSystemOnce; diff --git a/lightyear/src/lib.rs b/lightyear/src/lib.rs index 95d6a96f6..f1456916d 100644 --- a/lightyear/src/lib.rs +++ b/lightyear/src/lib.rs @@ -230,6 +230,7 @@ pub mod prelude { pub use crate::shared::time_manager::TimeManager; pub use crate::transport::middleware::compression::CompressionConfig; pub use crate::transport::middleware::conditioner::LinkConditionerConfig; + pub use crate::utils::history_buffer::{HistoryBuffer, HistoryState}; mod rename { pub use crate::client::events::ComponentInsertEvent as ClientComponentInsertEvent; diff --git a/lightyear/src/client/prediction/history.rs b/lightyear/src/utils/history_buffer.rs similarity index 94% rename from lightyear/src/client/prediction/history.rs rename to lightyear/src/utils/history_buffer.rs index 0b73a1b0f..cbf99b42c 100644 --- a/lightyear/src/client/prediction/history.rs +++ b/lightyear/src/utils/history_buffer.rs @@ -7,7 +7,7 @@ use tracing::debug; /// Stores a past value in the history buffer #[derive(Debug, PartialEq, Clone, Default, Reflect)] -pub(crate) enum HistoryState { +pub enum HistoryState { // we add a Default implementation simply so that Reflection works #[default] /// the value just got removed @@ -20,7 +20,7 @@ pub(crate) enum HistoryState { /// The values must always remain ordered from oldest (front) to most recent (back) #[derive(Resource, Component, Debug, Reflect)] #[reflect(Component, Resource)] -pub(crate) struct HistoryBuffer { +pub struct HistoryBuffer { // Queue containing the history of the resource. // The front contains old elements, the back contains the more recent elements. // We will only store the history for the ticks where the resource got updated @@ -53,23 +53,23 @@ impl PartialEq for HistoryBuffer { impl HistoryBuffer { /// Reset the history for this resource - pub(crate) fn clear(&mut self) { + pub fn clear(&mut self) { self.buffer.clear(); } /// Add to the buffer that we received an update for the resource at the given tick /// The tick must be more recent than the most recent update in the buffer - pub(crate) fn add_update(&mut self, tick: Tick, value: R) { + pub fn add_update(&mut self, tick: Tick, value: R) { self.add(tick, Some(value)); } /// Add to the buffer that the value got removed at the given tick - pub(crate) fn add_remove(&mut self, tick: Tick) { + pub fn add_remove(&mut self, tick: Tick) { self.add(tick, None); } /// Add a value to the history buffer /// The tick must be strictly more recent than the most recent update in the buffer - pub(crate) fn add(&mut self, tick: Tick, value: Option) { + pub fn add(&mut self, tick: Tick, value: Option) { if let Some(last_tick) = self.peek().map(|(tick, _)| tick) { // assert!( // tick >= *last_tick, @@ -91,7 +91,7 @@ impl HistoryBuffer { } /// Peek at the most recent value in the history buffer - pub(crate) fn peek(&self) -> Option<&(Tick, HistoryState)> { + pub fn peek(&self) -> Option<&(Tick, HistoryState)> { self.buffer.back() } @@ -114,7 +114,7 @@ impl HistoryBuffer { /// (i.e. if the buffer contains values at tick 4 and 8. If we pop_until_tick(6), we cannot delete the value for tick 4 /// because we still need in case we call pop_until_tick(7). What we'll do is remove the value for tick 4 and re-insert it /// for tick 6) - pub(crate) fn pop_until_tick(&mut self, tick: Tick) -> Option> { + pub fn pop_until_tick(&mut self, tick: Tick) -> Option> { // self.buffer[partition] is the first element where the buffer_tick > tick let partition = self .buffer diff --git a/lightyear/src/utils/mod.rs b/lightyear/src/utils/mod.rs index c678800e4..f89103cf9 100644 --- a/lightyear/src/utils/mod.rs +++ b/lightyear/src/utils/mod.rs @@ -17,5 +17,6 @@ pub mod avian2d; pub mod avian3d; pub(crate) mod captures; +pub(crate) mod history_buffer; pub(crate) mod pool; pub mod wrapping_id; From 5e848b0cd8fef596eb30f1cb257c16745617bd4d Mon Sep 17 00:00:00 2001 From: cBournhonesque Date: Sun, 19 Jan 2025 17:33:19 -0500 Subject: [PATCH 2/2] make history buffer pub --- lightyear/src/client/prediction/mod.rs | 1 - lightyear/src/client/prediction/prespawn.rs | 1 - lightyear/src/client/prediction/resource_history.rs | 3 +-- lightyear/src/client/prediction/rollback.rs | 3 +-- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lightyear/src/client/prediction/mod.rs b/lightyear/src/client/prediction/mod.rs index e04685b12..86360b43b 100644 --- a/lightyear/src/client/prediction/mod.rs +++ b/lightyear/src/client/prediction/mod.rs @@ -8,7 +8,6 @@ use std::fmt::Debug; pub mod correction; pub mod despawn; pub mod diagnostics; -mod history; pub mod plugin; pub mod pre_prediction; pub mod predicted_history; diff --git a/lightyear/src/client/prediction/prespawn.rs b/lightyear/src/client/prediction/prespawn.rs index 113a21080..a22fd6845 100644 --- a/lightyear/src/client/prediction/prespawn.rs +++ b/lightyear/src/client/prediction/prespawn.rs @@ -495,7 +495,6 @@ impl Component for PreSpawnedPlayerObject { #[cfg(test)] mod tests { - use crate::client::prediction::history::HistoryState; use crate::client::prediction::predicted_history::PredictionHistory; use crate::client::prediction::resource::PredictionManager; use crate::prelude::client::{is_in_rollback, PredictionDespawnCommandsExt, PredictionSet}; diff --git a/lightyear/src/client/prediction/resource_history.rs b/lightyear/src/client/prediction/resource_history.rs index 11adb7fba..c32df6231 100644 --- a/lightyear/src/client/prediction/resource_history.rs +++ b/lightyear/src/client/prediction/resource_history.rs @@ -1,9 +1,8 @@ //! There's a lot of overlap with `client::prediction_history` because resources are components in ECS so rollback is going to look similar. -use crate::prelude::TickManager; +use crate::prelude::{HistoryBuffer, HistoryState, TickManager}; use bevy::prelude::*; use super::rollback::Rollback; -use crate::client::prediction::history::{HistoryBuffer, HistoryState}; use crate::shared::tick_manager::TickEvent; pub(crate) type ResourceHistory = HistoryBuffer; diff --git a/lightyear/src/client/prediction/rollback.rs b/lightyear/src/client/prediction/rollback.rs index 147414352..c371b5c20 100644 --- a/lightyear/src/client/prediction/rollback.rs +++ b/lightyear/src/client/prediction/rollback.rs @@ -18,9 +18,8 @@ use crate::client::config::ClientConfig; use crate::client::connection::ConnectionManager; use crate::client::prediction::correction::Correction; use crate::client::prediction::diagnostics::PredictionMetrics; -use crate::client::prediction::history::HistoryState; use crate::client::prediction::resource::PredictionManager; -use crate::prelude::{ComponentRegistry, PreSpawnedPlayerObject, Tick, TickManager}; +use crate::prelude::{ComponentRegistry, HistoryState, PreSpawnedPlayerObject, Tick, TickManager}; use super::predicted_history::PredictionHistory; use super::resource_history::ResourceHistory;