Struct maskerad_memory_allocators::StackAllocator [] [src]

pub struct StackAllocator { /* fields omitted */ }

A stack-based allocator for data implementing the Drop trait.

It manages a MemoryChunk to:

  • Allocate bytes in a stack-like fashion.

  • Store different types of objects in the same storage.

  • Drop the content of the MemoryChunk when needed.

Instantiation

When instantiated, the memory chunk pre-allocate the given number of bytes.

Allocation

When an object is allocated in memory, the allocator:

  • Asks a pointer to a memory address to its memory chunk,

  • Place the object in this memory address,

  • Update the first unused memory address of the memory chunk according to an offset,

  • And return a mutable reference to the object which has been placed in the memory chunk.

This offset is calculated by the size of the object, the size of a TypeDescription structure, its memory-alignment and an offset to align the object in memory.

Roll-back

This structure allows you to get a marker, the index to the first unused memory address of the memory chunk. A stack allocator can be reset to a marker, or reset entirely.

When the allocator is reset to a marker, the memory chunk will drop all the content lying between the marker and the first unused memory address, and set the first unused memory address to the marker.

When the allocator is reset completely, the memory chunk will drop everything and set the first unused memory address to the bottom of its stack.

Example

use maskerad_memory_allocators::StackAllocator;

struct Monster {
    hp :u32,
    level: u32,
}

impl Default for Monster {
    fn default() -> Self {
        Monster {
        hp: 1,
        level: 1,
        }
    }
}

impl Drop for Monster {
    fn drop(&mut self) {
        println!("I'm dying !");
    }
}

let single_frame_allocator = StackAllocator::with_capacity(100); //100 bytes
let mut closed = false;

while !closed {
    // The allocator is cleared every frame.
    // (Everything is dropped, and allocation occurs from the bottom of the stack).
    single_frame_allocator.reset();

    //...

    //allocate from the single frame allocator.
    //Be sure to use the data during this frame only!
    let my_monster = single_frame_allocator.alloc(|| {
        Monster::default()
    });

    assert_eq!(my_monster.level, 1);
    closed = true;
}

Methods

impl StackAllocator
[src]

[src]

Creates a StackAllocator with the given capacity, in bytes.

Example

#![feature(alloc)]
use maskerad_memory_allocators::StackAllocator;

let allocator = StackAllocator::with_capacity(100);
assert_eq!(allocator.storage().borrow().capacity(), 100);

[src]

Returns an immutable reference to the memory chunk used by the allocator.

[src]

Allocates data in the allocator's memory.

Panics

This function will panic if the allocation exceeds the maximum storage capacity of the allocator.

Example

use maskerad_memory_allocators::StackAllocator;

let allocator = StackAllocator::with_capacity(100);

let my_i32 = allocator.alloc(|| {
    26 as i32
});
assert_eq!(my_i32, &mut 26);

[src]

Returns the index of the first unused memory address.

Example

use maskerad_memory_allocators::StackAllocator;

let allocator = StackAllocator::with_capacity(100); //100 bytes

//Get the raw pointer to the bottom of the allocator's memory chunk.
let start_allocator = allocator.storage().borrow().as_ptr();

//Get the index of the first unused memory address.
let index_current_top = allocator.marker();

//Calling offset() on a raw pointer is an unsafe operation.
unsafe {
    //Get the raw pointer, with the index.
    let current_top = start_allocator.offset(index_current_top as isize);

    //Nothing has been allocated in the allocator,
    //the top of the stack is the bottom of the allocator's memory chunk.
    assert_eq!(current_top, start_allocator);
}

[src]

Reset the allocator, dropping all the content residing inside it.

Example

use maskerad_memory_allocators::StackAllocator;

struct Monster {
    hp :u32,
}

impl Default for Monster {
    fn default() -> Self {
        Monster {
        hp: 1,
        }
    }
}

impl Drop for Monster {
    fn drop(&mut self) {
        println!("Monster is dying !");
    }
}

struct Dragon {
    level: u8,
}

impl Default for Dragon {
    fn default() -> Self {
        Dragon {
            level: 1,
        }
    }
}

impl Drop for Dragon {
    fn drop(&mut self) {
        println!("Dragon is dying !");
    }
}

let allocator = StackAllocator::with_capacity(100); // 100 bytes.

//When nothing has been allocated, the first unused memory address is at index 0.
assert_eq!(allocator.marker(), 0);

let my_monster = allocator.alloc(|| {
    Monster::default()
});
assert_ne!(allocator.marker(), 0);

let my_dragon = allocator.alloc(|| {
    Dragon::default()
});

allocator.reset();

//The allocator has been totally reset, and all its content has been dropped.
//my_monster has printed "Monster is dying!".
//my_dragon has printed "Dragon is dying!".
assert_eq!(allocator.marker(), 0);

[src]

Reset partially the allocator, dropping all the content residing between the marker and the first unused memory address of the allocator.

Example

use maskerad_memory_allocators::StackAllocator;

struct Monster {
    hp :u32,
}

impl Default for Monster {
    fn default() -> Self {
        Monster {
        hp: 1,
        }
    }
}

impl Drop for Monster {
    fn drop(&mut self) {
        println!("Monster is dying !");
    }
}

struct Dragon {
    level: u8,
}

impl Default for Dragon {
    fn default() -> Self {
        Dragon {
            level: 1,
        }
    }
}

impl Drop for Dragon {
    fn drop(&mut self) {
        println!("Dragon is dying !");
    }
}

let allocator = StackAllocator::with_capacity(100); // 100 bytes.

//When nothing has been allocated, the first unused memory address is at index 0.
assert_eq!(allocator.marker(), 0);

let my_monster = allocator.alloc(|| {
    Monster::default()
});

//After the monster allocation, get the index of the first unused memory address in the allocator.
let index_current_top = allocator.marker();
assert_ne!(index_current_top, 0);

let my_dragon = allocator.alloc(|| {
    Dragon::default()
});

assert_ne!(allocator.marker(), index_current_top);

allocator.reset_to_marker(index_current_top);

//The allocator has been partially reset, and all the content lying between the marker and
//the first unused memory address has been dropped.
//my_dragon has printed "Dragon is dying!".

assert_eq!(allocator.marker(), index_current_top);

Trait Implementations

impl Drop for StackAllocator
[src]

[src]

Executes the destructor for this type. Read more