A fixed set of lock-free occurrence counters. More...
#include <activity_channel.hpp>
Public Types | |
| using | Sequence = std::uint32_t |
Public Member Functions | |
| void | signal (std::size_t lane) noexcept |
Record activity on lane. | |
| Sequence | sequence (std::size_t lane) const noexcept |
Read the current sequence for lane. Invalid lanes read as zero. | |
| bool | consume (std::size_t lane, Sequence &cursor) const noexcept |
Return true once when activity has occurred since cursor was last consumed, updating the cursor to the newest sequence. | |
| Sequence | consume_count (std::size_t lane, Sequence &cursor) const noexcept |
Return the number of signals since cursor and advance it to the newest sequence. | |
Static Public Member Functions | |
| static constexpr std::size_t | lane_count () noexcept |
A fixed set of lock-free occurrence counters.
This channel is for payload-free occurrences whose complete meaning is "lane N was active": MIDI pad flashes, clipping indicators, manual trigger requests, and similar signals. Producers call signal() from either side; each consumer keeps one Sequence cursor per lane. consume() intentionally coalesces a burst into one observation, while consume_count() preserves the number of occurrences for command paths that must replay every trigger. signal() is multi-producer safe; consumers are independent because each owns its cursor.
The channel carries no associated payload, so relaxed atomic ordering is sufficient. It allocates nothing and takes no locks in signal(). Share the channel with a view through SharedActivityChannel so a host that retains an editor after destroying its Processor cannot leave the view polling freed processor memory. Sequence wrap is harmless for ordinary polling; only an exact multiple of 2^32 unconsumed signals can alias the cursor.
| using pulp::runtime::ActivityChannel< LaneCount >::Sequence = std::uint32_t |
|
inlinenoexcept |
Return true once when activity has occurred since cursor was last consumed, updating the cursor to the newest sequence.
A burst may advance by more than one, but is deliberately reported as one visual wake-up rather than a queue of stale flashes.
|
inlinenoexcept |
Return the number of signals since cursor and advance it to the newest sequence.
Unsigned subtraction deliberately handles sequence wrap. Invalid lanes return zero and leave the cursor untouched.
|
inlinestaticconstexprnoexcept |
|
inlinenoexcept |
Read the current sequence for lane. Invalid lanes read as zero.
|
inlinenoexcept |
Record activity on lane.
Invalid lanes are ignored so a realtime producer can fail closed without exceptions, logging, or assertions.