Gamedev Framework (gf)  0.19.0
A C++17 framework for 2D games
BlockAllocator.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2021 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_SPATIAL_BLOCK_ALLOCATOR_H
22 #define GF_SPATIAL_BLOCK_ALLOCATOR_H
23 
24 #include <cassert>
25 #include <vector>
26 
27 namespace gf {
28 #ifndef DOXYGEN_SHOULD_SKIP_THIS
29 inline namespace v1 {
30 #endif
31 
38  constexpr std::size_t NullIndex = static_cast<std::size_t>(-1);
39 
44  template<typename T>
46  public:
51  : m_firstFreeBlock(NullIndex)
52  , m_allocated(0)
53  {
54  }
55 
61  std::size_t allocate() {
62  std::size_t index = NullIndex;
63 
64  if (m_firstFreeBlock != NullIndex) {
65  index = m_firstFreeBlock;
66  m_firstFreeBlock = m_blocks[index].next;
67  m_blocks[index].next = NullIndex;
68  } else {
69  index = m_blocks.size();
70  m_blocks.push_back(Block());
71  }
72 
73  assert(index < m_blocks.size());
74  assert(m_blocks[index].next == NullIndex);
75 
76  ++m_allocated;
77  return index;
78  }
79 
87  void dispose(std::size_t index) {
88  assert(index < m_blocks.size());
89  m_blocks[index].next = m_firstFreeBlock;
90  m_firstFreeBlock = index;
91  --m_allocated;
92  }
93 
99  T& operator[](std::size_t index) {
100  assert(index < m_blocks.size());
101  assert(m_blocks[index].next == NullIndex);
102  return m_blocks[index].data;
103  }
104 
110  const T& operator[](std::size_t index) const {
111  assert(index < m_blocks.size());
112  assert(m_blocks[index].next == NullIndex);
113  return m_blocks[index].data;
114  }
115 
119  void clear() {
120  m_firstFreeBlock = NullIndex;
121  m_blocks.clear();
122  }
123 
129  std::size_t getAllocated() const {
130  return m_allocated;
131  }
132 
133  private:
134  struct Block {
135  T data;
136  std::size_t next = NullIndex;
137  };
138 
139  std::size_t m_firstFreeBlock;
140  std::vector<Block> m_blocks;
141  std::size_t m_allocated;
142  };
143 
144 
145 #ifndef DOXYGEN_SHOULD_SKIP_THIS
146 }
147 #endif
148 }
149 
150 
151 #endif // GF_SPATIAL_BLOCK_ALLOCATOR_H
const T & operator[](std::size_t index) const
Access the object at a given index.
Definition: BlockAllocator.h:110
void dispose(std::size_t index)
Deallocate the object at the given index.
Definition: BlockAllocator.h:87
T & operator[](std::size_t index)
Access the object at a given index.
Definition: BlockAllocator.h:99
std::size_t getAllocated() const
Get the number of allocated objects.
Definition: BlockAllocator.h:129
The namespace for gf classes.
Definition: Action.h:35
An allocator of objects referenced by an index.
Definition: BlockAllocator.h:45
constexpr std::size_t NullIndex
A null index in a block allocator.
Definition: BlockAllocator.h:38
std::size_t allocate()
Allocate an object.
Definition: BlockAllocator.h:61
The socket would have blocked.
BlockAllocator()
Default constructor.
Definition: BlockAllocator.h:50
void clear()
Remove all objects at once.
Definition: BlockAllocator.h:119