pooled

Macro pooled 

Source
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);
}