pub struct DoubleBuffer<T> { /* private fields */ }
Expand description
Encapsulates a piece of state that can be modified and we want all outside code to see the edit as a single atomic change.
§Trait implementations
If trait use an immutable reference (AsRef<T>
, Deref
, Borrow<T>
…) give access to the current value
and mutable references (AsMut<T>
, DerefMut
, BorrowMut<T>
…) give access to the next value.
§Swapping
There are three ways to swap:
DoubleBuffer::swap()
- when swapping, the next value will have the previous current value.DoubleBuffer::swap_with_clone()
- when swapping, the next value will keep same and will be cloned to the current value.DoubleBuffer::swap_with_default()
- likeDoubleBuffer::swap()
but the next value will be set to the default value of the type.
Note that for the third way, the type must implement Default
.
You can read about the two ways how the buffers are swapped in “Game Programming Patterns” by Robert Nystrom.
§Swapping performance
If it’s not important to keep the pointer address of the current value unchanged,
DoubleBuffer::swap()
is the best option.
Or DoubleBuffer::swap_with_default()
if the type implements Default
and
starts with the default value is important.
Only use DoubleBuffer::swap_with_clone()
if it’s important to keep the pointer
address of the current value unchanged.
§Examples
The following example shows how the buffer is swapped with the three ways:
let mut buffer: DoubleBuffer<[u8; 32]> = DoubleBuffer::default();
print!("{:?}", buffer); // DoubleBuffer { current: [0, ...], next: [0, ...] }
buffer[0] = 1;
print!("{:?}", buffer); // DoubleBuffer { current: [0, ...], next: [1, ...] }
buffer.swap();
print!("{:?}", buffer); // DoubleBuffer { current: [1, ...], next: [0, ...] }
buffer[0] = 2;
print!("{:?}", buffer); // DoubleBuffer { current: [1, ...], next: [2, ...] }
buffer.swap_with_clone();
print!("{:?}", buffer); // DoubleBuffer { current: [2, ...], next: [2, ...] }
buffer[0] = 3;
print!("{:?}", buffer); // DoubleBuffer { current: [2, ...], next: [3, ...] }
buffer.swap_with_default();
print!("{:?}", buffer); // DoubleBuffer { current: [3, ...], next: [0, ...] }
Implementations§
Source§impl<T> DoubleBuffer<T>
impl<T> DoubleBuffer<T>
pub const fn new(current: T, next: T) -> Self
Sourcepub fn swap(&mut self)
pub fn swap(&mut self)
Swaps the current and next values, then writes will be over the previous current value.
This changes the pointer address of the current value.
§Examples
let mut buffer: DoubleBuffer<[u8; 8192]> = DoubleBuffer::new([0; 8192], [0; 8192]);
let first_address = format!("{:p}", buffer);
buffer.swap();
let second_address = format!("{:p}", buffer);
// The addresses are different.
assert_ne!(first_address, second_address);
Source§impl<T: Clone> DoubleBuffer<T>
impl<T: Clone> DoubleBuffer<T>
Sourcepub fn swap_with_clone(&mut self)
pub fn swap_with_clone(&mut self)
Clone the next value to the current value, then writes will continue over the same next value.
This let the pointer address of the current value unchanged.
§Examples
let mut buffer: DoubleBuffer<[u8; 8192]> = DoubleBuffer::new([0; 8192], [0; 8192]);
let first_address = format!("{:p}", buffer);
buffer.swap_with_clone();
let second_address = format!("{:p}", buffer);
// The addresses are different.
assert_eq!(first_address, second_address);
Source§impl<T: Default> DoubleBuffer<T>
impl<T: Default> DoubleBuffer<T>
Sourcepub fn swap_with_default(&mut self)
pub fn swap_with_default(&mut self)
Swaps buffers like DoubleBuffer::swap()
and sets the next
value to the default value of the type, then writes will be
over the default value.