/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/ThirdParty/RmlUi/Source/Core/Pool.inl
232 строки
5 KB
C-Core
Updated RmlUi to 6.2 and added some improvements (#1813)
10 фев 2026, 01:19
Не верифицирован
10 фев 2026, 01:19
58e2d41
Код
Авторство
О чём код?
namespace Rml { template < typename PoolType > Pool< PoolType >::Pool(int _chunk_size, bool _grow) { chunk_size = 0; grow = _grow; num_allocated_objects = 0; pool = nullptr; first_allocated_node = nullptr; first_free_node = nullptr; if (_chunk_size > 0) Initialise(_chunk_size, _grow); } template < typename PoolType > Pool< PoolType >::~Pool() { RMLUI_ASSERT(num_allocated_objects == 0); PoolChunk* chunk = pool; while (chunk) { PoolChunk* next_chunk = chunk->next; delete[] chunk->chunk; delete chunk; chunk = next_chunk; } } // Initialises the pool to a given size. template < typename PoolType > void Pool< PoolType >::Initialise(int _chunk_size, bool _grow) { // Should resize the pool here ... ? if (chunk_size > 0) return; if (_chunk_size <= 0) return; grow = _grow; chunk_size = _chunk_size; pool = nullptr; // Create the initial chunk. CreateChunk(); } // Returns the head of the linked list of allocated objects. template < typename PoolType > typename Pool< PoolType >::Iterator Pool< PoolType >::Begin() { return typename Pool< PoolType >::Iterator(first_allocated_node); } // Attempts to allocate a deallocated object in the memory pool. template<typename PoolType> template<typename ...Args> inline PoolType* Pool<PoolType>::AllocateAndConstruct(Args&&... args) { // We can't allocate a new object if the deallocated list is empty. if (first_free_node == nullptr) { // Attempt to grow the pool first. if (grow) { CreateChunk(); if (first_free_node == nullptr) return nullptr; } else return nullptr; } // We're about to allocate an object. ++num_allocated_objects; #ifdef RMLUI_DEBUG if (num_allocated_objects > max_num_allocated_objects) max_num_allocated_objects = num_allocated_objects; #endif // This one! PoolNode* allocated_object = first_free_node; // Remove the newly allocated object from the list of deallocated objects. first_free_node = first_free_node->next; if (first_free_node != nullptr) first_free_node->previous = nullptr; // Add the newly allocated object to the head of the list of allocated objects. if (first_allocated_node != nullptr) { allocated_object->previous = nullptr; allocated_object->next = first_allocated_node; first_allocated_node->previous = allocated_object; } else { // This object is the only allocated object. allocated_object->previous = nullptr; allocated_object->next = nullptr; } first_allocated_node = allocated_object; return new (allocated_object->object) PoolType(std::forward<Args>(args)...); } // Deallocates the object pointed to by the given iterator. template < typename PoolType > void Pool< PoolType >::DestroyAndDeallocate(Iterator& iterator) { // We're about to deallocate an object. --num_allocated_objects; PoolNode* object = iterator.node; reinterpret_cast<PoolType*>(object->object)->~PoolType(); // Get the previous and next pointers now, because they will be overwritten // before we're finished. PoolNode* previous_object = object->previous; PoolNode* next_object = object->next; if (previous_object != nullptr) previous_object->next = next_object; else { RMLUI_ASSERT(first_allocated_node == object); first_allocated_node = next_object; } if (next_object != nullptr) next_object->previous = previous_object; // Insert the freed node at the beginning of the free object list. if (first_free_node == nullptr) { object->previous = nullptr; object->next = nullptr; } else { object->previous = nullptr; object->next = first_free_node; } first_free_node = object; // Increment the iterator, so it points to the next active object. iterator.node = next_object; } // Deallocates the given object. template < typename PoolType > void Pool< PoolType >::DestroyAndDeallocate(PoolType* object) { // This assumes the object has the same address as the node, which will be // true as long as the struct definition does not change. Iterator iterator((PoolNode*) object); DestroyAndDeallocate(iterator); } // Returns the number of objects in the pool. template < typename PoolType > int Pool< PoolType >::GetSize() const { return chunk_size * GetNumChunks(); } /// Returns the number of object chunks in the pool. template < typename PoolType > int Pool< PoolType >::GetNumChunks() const { int num_chunks = 0; PoolChunk* chunk = pool; while (chunk != nullptr) { ++num_chunks; chunk = chunk->next; } return num_chunks; } // Returns the number of allocated objects in the pool. template < typename PoolType > int Pool< PoolType >::GetNumAllocatedObjects() const { return num_allocated_objects; } // Creates a new pool chunk and appends its nodes to the beginning of the free list. template < typename PoolType > void Pool< PoolType >::CreateChunk() { if (chunk_size <= 0) return; // Create the new chunk and mark it as the first chunk. PoolChunk* new_chunk = new PoolChunk(); new_chunk->next = pool; pool = new_chunk; // Create chunk's pool nodes. new_chunk->chunk = new PoolNode[chunk_size]; // Initialise the linked list. for (int i = 0; i < chunk_size; i++) { if (i == 0) new_chunk->chunk[i].previous = nullptr ; else new_chunk->chunk[i].previous = &new_chunk->chunk[i - 1]; if (i == chunk_size - 1) new_chunk->chunk[i].next = first_free_node; else new_chunk->chunk[i].next = &new_chunk->chunk[i + 1]; } first_free_node = new_chunk->chunk; } } // namespace Rml