|
1 /* $Id$ */ |
|
2 |
|
3 #ifndef POOL_H |
|
4 #define POOL_H |
|
5 |
|
6 typedef struct OldMemoryPool OldMemoryPool; |
|
7 |
|
8 /* The function that is called after a new block is added |
|
9 start_item is the first item of the new made block */ |
|
10 typedef void OldMemoryPoolNewBlock(uint start_item); |
|
11 /* The function that is called before a block is cleaned up */ |
|
12 typedef void OldMemoryPoolCleanBlock(uint start_item, uint end_item); |
|
13 |
|
14 /** |
|
15 * Stuff for dynamic vehicles. Use the wrappers to access the OldMemoryPool |
|
16 * please try to avoid manual calls! |
|
17 */ |
|
18 struct OldMemoryPool { |
|
19 const char* const name; ///< Name of the pool (just for debugging) |
|
20 |
|
21 const uint max_blocks; ///< The max amount of blocks this pool can have |
|
22 const uint block_size_bits; ///< The size of each block in bits |
|
23 const uint item_size; ///< How many bytes one block is |
|
24 |
|
25 /// Pointer to a function that is called after a new block is added |
|
26 OldMemoryPoolNewBlock *new_block_proc; |
|
27 /// Pointer to a function that is called to clean a block |
|
28 OldMemoryPoolCleanBlock *clean_block_proc; |
|
29 |
|
30 uint current_blocks; ///< How many blocks we have in our pool |
|
31 uint total_items; ///< How many items we now have in this pool |
|
32 |
|
33 byte **blocks; ///< An array of blocks (one block hold all the items) |
|
34 }; |
|
35 |
|
36 /** |
|
37 * Those are the wrappers: |
|
38 * CleanPool cleans the pool up, but you can use AddBlockToPool directly again |
|
39 * (no need to call CreatePool!) |
|
40 * AddBlockToPool adds 1 more block to the pool. Returns false if there is no |
|
41 * more room |
|
42 */ |
|
43 void CleanPool(OldMemoryPool *array); |
|
44 bool AddBlockToPool(OldMemoryPool *array); |
|
45 |
|
46 /** |
|
47 * Adds blocks to the pool if needed (and possible) till index fits inside the pool |
|
48 * |
|
49 * @return Returns false if adding failed |
|
50 */ |
|
51 bool AddBlockIfNeeded(OldMemoryPool *array, uint index); |
|
52 |
|
53 |
|
54 #define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ |
|
55 enum { \ |
|
56 name##_POOL_BLOCK_SIZE_BITS = block_size_bits, \ |
|
57 name##_POOL_MAX_BLOCKS = max_blocks \ |
|
58 }; |
|
59 |
|
60 |
|
61 #define OLD_POOL_ACCESSORS(name, type) \ |
|
62 static inline type* Get##name(uint index) \ |
|
63 { \ |
|
64 assert(index < _##name##_pool.total_items); \ |
|
65 return (type*)( \ |
|
66 _##name##_pool.blocks[index >> name##_POOL_BLOCK_SIZE_BITS] + \ |
|
67 (index & ((1 << name##_POOL_BLOCK_SIZE_BITS) - 1)) * sizeof(type) \ |
|
68 ); \ |
|
69 } \ |
|
70 \ |
|
71 static inline uint Get##name##PoolSize(void) \ |
|
72 { \ |
|
73 return _##name##_pool.total_items; \ |
|
74 } |
|
75 |
|
76 |
|
77 #define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \ |
|
78 OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ |
|
79 extern OldMemoryPool _##name##_pool; \ |
|
80 OLD_POOL_ACCESSORS(name, type) |
|
81 |
|
82 |
|
83 #define DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \ |
|
84 OldMemoryPool _##name##_pool = { \ |
|
85 #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \ |
|
86 new_block_proc, clean_block_proc, \ |
|
87 0, 0, NULL \ |
|
88 }; |
|
89 |
|
90 |
|
91 #define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \ |
|
92 OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ |
|
93 static DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \ |
|
94 OLD_POOL_ACCESSORS(name, type) |
|
95 |
|
96 #endif /* POOL_H */ |