Code design: object pool


#1

I have the following situation:

pub struct SpriteBatchItem<'a> {
    texture: &'a Texture<'a>,
    vertexTL: VertexPositionColorTexture,
    vertexTR: VertexPositionColorTexture,
    vertexBL: VertexPositionColorTexture,
    vertexBR: VertexPositionColorTexture,
    sortKey: f32,
}

pub struct SpriteBatcher<'a> {
    initial_batch_size: i32,
    max_batch_size: i32,
    initial_vertex_array_size: i32,
    renderer: &'a RendererContext,
    graphics_device: &'a GraphicsDevice,
    batch_item_list: mut Vec<SpriteBatchItem>, /// The list of batch items to process.
    batch_item_count: i32, /// Index pointer to the next available SpriteBatchItem in _batchItemList.
    index: Vec<i32>, /// Vertex index array. The values in this array never change.
    vertex_array: Vec<VertexPositionColorTexture>,
}

Now let’s just ignore all of the properties of the SpriteBatcher struct, except of the batch_item_list. That batch_item_list is actually a sort of object pool that I want to pre-allocate when I create a new SpriteBatcher instance.

But since the SpriteBatchItem contains lots of properties that I cannot fill in ahead of time, what would be the correct approach? With standard C code I’d just make all the pointers NULL and initialize floats and integers with zero values and that’s it. But since Rust doesn’t allow NULL pointers, what would be the correct way to write this kind of code?

Cheers!


#2

You can’t put mut there in Rust.

Probably there are multiple ways to solve this, but a basic strategy is to initialize integers and FP values to zero as in C and use Option<Box<...>> for the pointers.


#3

I tried with texture: <Option<Box<Texture<'a>>>>, in SpriteBatchItem but the compiler is complaining that there’s a comma while there should be double colons there:

error: expected `::`, found `,`
 --> src/spritebatchitem.rs:9:40
  |
9 |     texture: <Option<Box<Texture<'a>>>>,
  |                                        ^

#4

As I’ve been pointed out the error is that I’m wrapping option in a diamond where there should be none :stuck_out_tongue:


#5

Note that Option<Box<Texture<'a>>> means you may contain an owned heap allocated Texture. That’s a bit different from the semantics you had in the initial post, where it was &'a Texture<'a>. Maybe you want Option<&'a Texture<'a>>?


#6

Yes, that’s probably more like what I need. Or I might as well just box the texture in the first place when it is instantiated. But that’s pretty much a wrapper around the rust-sdl2 texture object so I suspect that SDL2 is already allocating it on the heap on its own so I can just pass around the reference as you said as my wrapper is only a tiny layer.


#7

I’m probably not understanding what you want to accomplish, but if you want to “oversize” the Vec, then Vec::with_capacity(usize) will do that. You can easily add batch items with Vec::push.

https://is.gd/BQykF7

I suppose this won’t work if, later, you want to remove batch items and subsequently fill in the empty spots with with new batch items.