#pragma once uint16_t constexpr const_hash(const char* input) { return *input ? static_cast(*input) + 33 * const_hash(input + 1) : 5381; } bool point_in_rect(const glm::vec2& point, const glm::vec4& rect); glm::vec4 rand_color(); glm::vec3 convert_hsv2rgb(const glm::vec3 c); glm::vec3 convert_rgb2hsv(const glm::vec3 c); void check_OpenGLError(const char* stmt, const char* fname, int line); template struct cbuffer { T m_vec[N]; int m_capacity; int m_count; int m_index; cbuffer() { m_capacity = N; m_index = 0; m_count = 0; } T& head() { return m_index == 0 ? m_vec[m_count - 1] : m_vec[m_index - 1]; } void add(const T& v) { m_vec[m_index] = v; m_index = (m_index + 1) % m_capacity; m_count = m_count < m_capacity ? m_count + 1 : m_count; } int count() const { return m_count; } template T2 average() const { T2 tot{}; if (m_count == 0) return tot; for (int i = 0; i < m_count; i++) tot += m_vec[i]; return tot / (float)m_count; } }; NS_START template class BlockingQueue { std::deque q; std::condition_variable post_cv; std::condition_variable get_cv; mutable std::mutex mutex; public: volatile bool unlocked = false; BlockingQueue() = default; BlockingQueue(const BlockingQueue& other) = delete; BlockingQueue& operator=(const BlockingQueue& other) = delete; BlockingQueue(BlockingQueue&& other) : q(std::move(q)) { } BlockingQueue& operator=(BlockingQueue&& other) { q = std::move(q); return *this; } void Post(T&& pkt) { std::unique_lock lock(mutex); if (Max > 0) { post_cv.wait(lock, [&]() { return unlocked | (q.size() < Max); }); if (q.size() >= Max) return; } q.push_back(std::forward(pkt)); get_cv.notify_one(); } T Get() { static T emptyT{}; std::unique_lock lock(mutex); get_cv.wait(lock, [&]() { return unlocked | (q.size() > 0); }); if (q.empty()) return std::move(emptyT); T tmp = std::move(q.front()); q.pop_front(); if (Max > 0) post_cv.notify_all(); return std::move(tmp); } void UnlockGetters() { unlocked = true; get_cv.notify_all(); if (Max > 0) post_cv.notify_all(); } int Size() const { std::lock_guard lock(mutex); return (int)q.size(); } }; NS_END