| /* | |
| * Copyright 2022 Rive | |
| */ | |
| #pragma once | |
| #include "rive/pls/trivial_block_allocator.hpp" | |
| namespace rive::pls | |
| { | |
| // Fast, simple queue that operates on a block-allocated array. push_back() may only be called up to | |
| // m_capacity times before the queue must be rewound. | |
| template <typename T> class FixedQueue | |
| { | |
| public: | |
| void reset(TrivialArrayAllocator<T>& allocator, size_t capacity) | |
| { | |
| m_array = allocator.alloc(capacity); | |
| rewind(); | |
| RIVE_DEBUG_CODE(m_capacity = capacity;) | |
| } | |
| void rewind() { m_front = m_end = m_array; } | |
| void shrinkToFit(TrivialArrayAllocator<T>& allocator, size_t originalCapacity) | |
| { | |
| assert(m_capacity == originalCapacity); | |
| size_t newCapacity = m_end - m_array; | |
| assert(newCapacity <= originalCapacity); | |
| allocator.rewindLastAllocation(originalCapacity - newCapacity); | |
| RIVE_DEBUG_CODE(m_capacity = newCapacity;) | |
| } | |
| size_t pushCount() const { return m_end - m_array; } | |
| T& push_back() | |
| { | |
| assert(m_end < m_array + m_capacity); | |
| return *m_end++; | |
| } | |
| T& push_back(const T& t) { return push_back() = t; } | |
| T* push_back_n(size_t n) | |
| { | |
| assert(m_end + n <= m_array + m_capacity); | |
| T* ptr = m_end; | |
| m_end += n; | |
| return ptr; | |
| } | |
| const T& pop_front() | |
| { | |
| assert(m_front < m_end); | |
| return *m_front++; | |
| } | |
| const T* pop_front_n(size_t n) | |
| { | |
| assert(m_front + n <= m_end); | |
| const T* ptr = m_front; | |
| m_front += n; | |
| return ptr; | |
| } | |
| private: | |
| T* m_array = nullptr; | |
| T* m_front = nullptr; | |
| T* m_end = nullptr; | |
| RIVE_DEBUG_CODE(size_t m_capacity = 0;) | |
| }; | |
| } // namespace rive::pls |