macro_rules! pooled {
($(#[$outer:meta])* struct $name:ident {
$($field_name:ident: $field_type:ty,)*
}$(,)?
clear => $clear:expr) => { ... };
}
Expand description
Creates a struct that can be stored in an object pool, based on an inline struct definition.
In order to store a value in an object pool, the item must implement the Poolable
trait. This trait, and overall
design of ObjectPool
, dictates that a pooled data type actually holds an inner value, which
is the value that is actually pooled, while the outer struct is simply a wrapper around the data that ensures it is
returned to the object pool when no longer in use.
In practice, this means that if you wanted to create some struct that could be pooled (for example,
SimpleBuffer
), you would need to create that struct and bake in all of the boilerplate logic and
implementations for Poolable
/Clearable
. Instead, pooled!
can be used to define the desired struct inline,
while the wrapper type that contains the relevant pooling logic and trait implementations is generated
automatically.
§Limitations
This macro is most appropriate when the desired struct is simple, such as only requiring control over the fields and
not the presence of any methods or trait implementations. If more control is required, consider using
pooled_newtype!
which can wrap over an existing struct defined outside of the macro.
§Clearing
All poolable types must provide logic for “clearing” the pooled item before it is returned to the object pool.
This is passed in as the clear
parameter to the macro, and must be a closure that takes a mutable reference to
the inner struct.
Note that due to macro hygiene, the closure’s only parameter cannot be named self
. In the usage example below, you can
see how this is named this
instead to avoid conflicts.
§Usage
use saluki_core::pooling::helpers::pooled;
pooled! {
/// A simple Poolable struct.
struct SimpleBuffer {
value: u32,
}
clear => |this| this.value = 0
}
// This creates a new struct called `SimpleBufferInner` based on the definition of `SimpleBuffer`,
// and `SimpleBuffer` contains the necessary logic/pointers to be stored in an object pool.
//
// Two helper methods are provided on the wrapper struct (`SimpleBuffer`, in this case), for accessing
// the inner data: `data` and `data_mut`. We can see them in use below:
impl SimpleBuffer {
pub fn value(&self) -> u32 {
self.data().value
}
pub fn multiply_by_two(&mut self) {
self.data_mut().value *= 2;
}
}
fn use_simple_buffer(mut buf: SimpleBuffer) {
let original_value = buf.value();
buf.multiply_by_two();
let doubled_value = buf.value();
assert_eq!(doubled_value, original_value * 2);
}