Loading...
Searching...
No Matches
EventRing.hpp
1#pragma once
2#include <Process/Monitoring/Monitor.hpp>
3
4#include <ossia/detail/lockfree_queue.hpp>
5
6#include <atomic>
7#include <cstddef>
8#include <cstdint>
9#include <utility>
10#include <vector>
11
12namespace Process
13{
25template <typename T, std::size_t N>
27{
28public:
29 EventRing()
30 : m_queue{N}
31 {
32 m_staged.reserve(N);
33 }
34 EventRing(const EventRing&) = delete;
35 EventRing& operator=(const EventRing&) = delete;
36
38 bool push(const T& e) noexcept
39 {
40 if(m_queue.try_enqueue(e))
41 return true;
42 m_dropped.fetch_add(1, std::memory_order_relaxed);
43 return false;
44 }
45
48 template <typename F>
49 int drain(F&& f)
50 {
51 const uint64_t frame = monitorFrame();
52 T e;
53 if(frame == 0)
54 {
55 int n = 0;
56 while(m_queue.try_dequeue(e))
57 {
58 f(std::as_const(e));
59 ++n;
60 }
61 return n;
62 }
63
64 if(frame != m_frame)
65 {
66 m_frame = frame;
67 m_staged.clear();
68 while(m_queue.try_dequeue(e))
69 m_staged.push_back(e);
70 }
71 for(const T& s : m_staged)
72 f(s);
73 return int(m_staged.size());
74 }
75
76 uint64_t dropped() const noexcept { return m_dropped.load(std::memory_order_relaxed); }
77
78private:
79 ossia::spsc_queue<T> m_queue;
80 std::atomic<uint64_t> m_dropped{0};
81
82 // GUI side
83 std::vector<T> m_staged;
84 uint64_t m_frame{};
85};
86}
Definition EventRing.hpp:27
bool push(const T &e) noexcept
Writer: false when the ring is full and e was dropped.
Definition EventRing.hpp:38
int drain(F &&f)
Definition EventRing.hpp:49
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
uint64_t monitorFrame() noexcept
Definition MonitorLink.cpp:27