// ------------------------- VSMPOOL.H ------------------------------
// VSpace library
// Designed and written by Javier Ar‚valo Baeza.
// Memory pools for allocating (and discarding?) textures.

#ifndef _VSMPOOL_H_
#define _VSMPOOL_H_

#ifndef _VSBASE_H_
#include "vsbase.h"
#endif

enum {
        // Action codes for alloc
    VSMPA_FAIL      = 0,
    VSMPA_CREATE,
    VSMPA_FREE,     // This one needs more work. By now, use VSMPA_CREATE
};

typedef struct {
    void **addr;    // The block address is stored in this pointer.
                    // Should the block be deallocated, *addr is NULLEd.
                    // Allows freeing, and also as sanity checking.
} VSMP_TPoolElement, *VSMP_PPoolElement;

typedef struct sVSMPPool {
    bool alloc;     // If this was allocated automatically.
    int w;          // Width of elements in the pool (power of 2).
    int h;          // Height of elements in the pool (power of 2).
    int n;          // Number of elements in the pool (size of 'el').
    byte *block;    // Start address of mem buffer.
    struct sVSMPPool *next, *prev;
    VSMP_TPoolElement el[];
} VSMP_TPool, *VSMP_PPool;

#define VSMP_SIZEPOOL(n) (sizeof(VSMP_TPool) + (n)*sizeof(VSMP_TPoolElement))

    // Init a memory pool of given size. Insert it in a chain of equal
    // pools. NULL mp means malloc()'ate it.
extern VSMP_PPool VSMP_Init(VSMP_PPool mp, VSMP_PPool *pchain, int n, int w, int h);

    // Alloc a block in a given memory pool chain.
extern bool VSMP_Alloc(VSMP_PPool *pchain, void **addr, int n, int w, int h, int action);

    // Dealloc a block in a given memory pool chain.
extern bool VSMP_Free(VSMP_PPool chain, void *addr);

    // Deallocate a full chain.
extern void VSMP_End(VSMP_PPool chain);

#endif

// ------------------------- VSMPOOL.H ------------------------------
