pub struct SnapshotBuffer<T: Interpolate> { /* private fields */ }Expand description
Timestamped states of one entity, in time order, read back at any time:
interpolated between two snapshots, predicted for a bounded time past the
newest, then held. Times are the sender’s, in seconds on any timeline you
like (for a remote entity use SnapshotStream, which also converts
your local clock).
Snapshots may arrive in any order and more than once.
use ponko::*;
let mut buffer = SnapshotBuffer::new();
buffer.push(1.0, vec3(10.0, 0.0, 0.0));
buffer.push(0.0, vec3(0.0, 0.0, 0.0)); // arrived late: still placed first
assert_eq!(buffer.push(1.0, vec3(99.0, 0.0, 0.0)), SnapshotPush::Duplicate);
let s = buffer.sample_at(0.25).unwrap();
assert_eq!(s.value, vec3(2.5, 0.0, 0.0));
assert_eq!(s.state, SnapshotState::Interpolated);
// Packets stop: predict for up to 0.25 s, then hold.
assert_eq!(buffer.sample_at(1.1).unwrap().state, SnapshotState::Extrapolated);
let held = buffer.sample_at(5.0).unwrap();
assert_eq!(held.state, SnapshotState::Held);
assert_eq!(held.value, vec3(12.5, 0.0, 0.0));Implementations§
Source§impl<T: Interpolate> SnapshotBuffer<T>
impl<T: Interpolate> SnapshotBuffer<T>
Sourcepub fn new() -> Self
pub fn new() -> Self
An empty buffer with the default SnapshotConfig.
let b = ponko::SnapshotBuffer::<f32>::new();
assert!(b.is_empty());Sourcepub fn with_config(config: SnapshotConfig) -> Self
pub fn with_config(config: SnapshotConfig) -> Self
An empty buffer. Panics if capacity is below 2 or a time setting is
negative or not finite.
use ponko::*;
let b = SnapshotBuffer::<f32>::with_config(SnapshotConfig { delay: 0.2, ..Default::default() });
assert_eq!(b.config().delay, 0.2);Sourcepub fn config(&self) -> SnapshotConfig
pub fn config(&self) -> SnapshotConfig
The settings it was made with.
assert_eq!(ponko::SnapshotBuffer::<f32>::new().config().delay, 0.1);Sourcepub fn push(&mut self, time: f64, value: T) -> SnapshotPush
pub fn push(&mut self, time: f64, value: T) -> SnapshotPush
Stores value, stamped time. Late snapshots go in at their place in
time; one with the same timestamp as a stored snapshot is ignored.
When the buffer is full the oldest snapshot is dropped.
use ponko::*;
let mut b = SnapshotBuffer::new();
assert_eq!(b.push(1.0, 1.0f32), SnapshotPush::Added);
assert_eq!(b.push(1.0, 1.0f32), SnapshotPush::Duplicate);
assert_eq!(b.push(f64::NAN, 1.0f32), SnapshotPush::Invalid);Sourcepub fn sample_at(&self, time: f64) -> Option<SnapshotSample<T>>
pub fn sample_at(&self, time: f64) -> Option<SnapshotSample<T>>
The state at time (the sender’s timeline): interpolated between the
snapshots around it; past the newest, predicted up to
max_extrapolation and then held
where the prediction ended; before the oldest, the oldest. None
while the buffer is empty. Allocation free.
use ponko::*;
let mut b = SnapshotBuffer::new();
assert!(b.sample_at(0.0).is_none());
b.push(0.0, 0.0f32);
b.push(1.0, 4.0);
assert_eq!(b.sample_at(0.5).unwrap().value, 2.0);Sourcepub fn sample(&self, now: f64) -> Option<SnapshotSample<T>>
pub fn sample(&self, now: f64) -> Option<SnapshotSample<T>>
The state to show at now, delay seconds
in the past; for buffers filled with times from the clock now is on.
use ponko::*;
let mut b = SnapshotBuffer::new();
b.push(0.0, 0.0f32);
b.push(1.0, 10.0);
assert_eq!(b.sample(0.6).unwrap().value, 5.0); // 0.6 - 0.1 s delaySourcepub fn latest_time(&self) -> Option<f64>
pub fn latest_time(&self) -> Option<f64>
Timestamp of the newest snapshot.
let mut b = ponko::SnapshotBuffer::new();
b.push(2.0, 0.0f32);
assert_eq!(b.latest_time(), Some(2.0));Sourcepub fn oldest_time(&self) -> Option<f64>
pub fn oldest_time(&self) -> Option<f64>
Timestamp of the oldest snapshot kept.
let mut b = ponko::SnapshotBuffer::new();
b.push(2.0, 0.0f32);
assert_eq!(b.oldest_time(), Some(2.0));Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Number of snapshots kept.
assert_eq!(ponko::SnapshotBuffer::<f32>::new().len(), 0);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether no snapshot is kept.
assert!(ponko::SnapshotBuffer::<f32>::new().is_empty());Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Drops every snapshot. Do this on a teleport, a respawn or a restart of the sender’s clock, so the entity jumps instead of sliding across.
let mut b = ponko::SnapshotBuffer::new();
b.push(0.0, 0.0f32);
b.clear();
assert!(b.is_empty());Sourcepub fn trim_before(&mut self, time: f64)
pub fn trim_before(&mut self, time: f64)
Drops snapshots that can no longer be shown at time or later: all
but the newest one at or before it.
let mut b = ponko::SnapshotBuffer::new();
for i in 0..5 { b.push(i as f64, 0.0f32); }
b.trim_before(3.5);
assert_eq!(b.oldest_time(), Some(3.0));Trait Implementations§
Source§impl<T: Clone + Interpolate> Clone for SnapshotBuffer<T>
impl<T: Clone + Interpolate> Clone for SnapshotBuffer<T>
Source§impl<T: Debug + Interpolate> Debug for SnapshotBuffer<T>
impl<T: Debug + Interpolate> Debug for SnapshotBuffer<T>
Source§impl<T: Interpolate> Default for SnapshotBuffer<T>
impl<T: Interpolate> Default for SnapshotBuffer<T>
Auto Trait Implementations§
impl<T> Forget for SnapshotBuffer<T>
impl<T> Freeze for SnapshotBuffer<T>
impl<T> RefUnwindSafe for SnapshotBuffer<T>
impl<T> Send for SnapshotBuffer<T>
impl<T> Sync for SnapshotBuffer<T>
impl<T> Unpin for SnapshotBuffer<T>
impl<T> UnsafeUnpin for SnapshotBuffer<T>
impl<T> UnwindSafe for SnapshotBuffer<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> Component for T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
impl<T> MaybeSync for T
impl<T> MaybeSync for T
Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().impl<T> SerializableAny for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.