9#include "arg_wrappers.hpp"
12#include "int_types.hpp"
13#include "introspect.hpp"
14#include "processor.hpp"
25template <
typename TickEvent,
typename FireEvent,
typename ResetEvent,
26 bool FireAfterTick,
typename Downstream>
29 static_assert(processor<Downstream, TickEvent, FireEvent>);
36 Downstream downstream;
38 template <
typename Abstime>
void pre_tick(Abstime abstime) {
39 if constexpr (!FireAfterTick) {
41 downstream.handle(FireEvent{abstime});
45 template <
typename Abstime>
void post_tick(Abstime abstime) {
48 if constexpr (FireAfterTick) {
50 downstream.handle(FireEvent{abstime});
58 explicit count_up_to(arg::threshold<u64> threshold, arg::limit<u64> limit,
59 arg::initial_count<u64> initial_count,
60 Downstream downstream)
61 : count(initial_count.value), init(initial_count.value),
62 thresh(threshold.value), lmt(limit.value),
63 downstream(std::move(downstream)) {
65 throw std::invalid_argument(
66 "count_up_to limit must be greater than initial_count");
69 [[nodiscard]]
auto introspect_node() const -> processor_info {
70 return processor_info(
this,
"count_up_to");
73 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
74 return downstream.introspect_graph().push_entry_point(
this);
77 void handle(TickEvent
const &event) {
78 pre_tick(event.abstime);
79 downstream.handle(event);
80 post_tick(event.abstime);
83 void handle(TickEvent &&event) {
84 auto const abstime =
event.abstime;
86 downstream.handle(std::move(event));
91 requires handler_for<Downstream, std::remove_cvref_t<E>>
92 void handle(E &&event) {
93 if constexpr (std::is_convertible_v<std::remove_cvref_t<E>,
97 downstream.handle(std::forward<E>(event));
100 void flush() { downstream.flush(); }
176template <
typename TickEvent,
typename FireEvent,
typename ResetEvent,
177 bool FireAfterTick,
typename Downstream>
180 Downstream downstream) {
181 return internal::count_up_to<TickEvent, FireEvent, ResetEvent,
182 FireAfterTick, Downstream>(
183 threshold, limit, initial_count, std::move(downstream));
197template <
typename TickEvent,
typename FireEvent,
typename ResetEvent,
198 bool FireAfterTick,
typename Downstream>
201 Downstream downstream) {
204 throw std::invalid_argument(
205 "count_down_to limit must be less than initial_count");
217 return internal::count_up_to<TickEvent, FireEvent, ResetEvent,
218 FireAfterTick, Downstream>(
219 threshold, limit, initial_count, std::move(downstream));
228 std::function<
u64()> count_fn;
232 template <
typename Func>
233 explicit count_access(Func count_func) : count_fn(count_func) {}
243template <
typename Event,
typename Downstream>
class count {
244 static_assert(processor<Downstream, Event>);
248 Downstream downstream;
251 access_tracker<count_access> trk;
254 explicit count(access_tracker<count_access> &&tracker,
255 Downstream downstream)
256 : downstream(std::move(downstream)), trk(std::move(tracker)) {
257 trk.register_access_factory([](
auto &tracker) {
259 return count_access([self] {
return self->ct; });
263 [[nodiscard]]
auto introspect_node() const -> processor_info {
264 return processor_info(
this,
"count");
267 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
268 return downstream.introspect_graph().push_entry_point(
this);
271 template <
typename E>
272 requires handler_for<Downstream, std::remove_cvref_t<E>>
273 void handle(E &&event) {
274 if constexpr (std::is_convertible_v<std::remove_cvref_t<E>, Event>)
276 downstream.handle(std::forward<E>(event));
279 void flush() { downstream.flush(); }
312template <
typename Event,
typename Downstream>
314 return internal::count<Event, Downstream>(std::move(tracker),
315 std::move(downstream));
Tracker that mediates access to objects via a tcspc::context.
Definition context.hpp:39
auto count() -> u64
Return the count value of the associated processor.
Definition count.hpp:238
#define LIBTCSPC_OBJECT_FROM_TRACKER(obj_type, tracker_field_name, tracker)
Recover the object address from a tcspc::access_tracker embedded in the object.
Definition context.hpp:253
auto count(access_tracker< count_access > &&tracker, Downstream downstream)
Create a processor that counts events of a given type.
Definition count.hpp:313
auto count_down_to(arg::threshold< u64 > threshold, arg::limit< u64 > limit, arg::initial_count< u64 > initial_count, Downstream downstream)
Like tcspc::count_up_to(), but decrement the count on each tick event.
Definition count.hpp:199
auto count_up_to(arg::threshold< u64 > threshold, arg::limit< u64 > limit, arg::initial_count< u64 > initial_count, Downstream downstream)
Create a processor that counts a specific event and emits an event when the count reaches a threshold...
Definition count.hpp:178
std::uint64_t u64
Short name for uint64_t.
Definition int_types.hpp:33
libtcspc namespace.
Definition acquire.hpp:29
Function argument wrapper for initial count parameter.
Definition arg_wrappers.hpp:167
T value
The argument value.
Definition arg_wrappers.hpp:169
Function argument wrapper for limit parameter.
Definition arg_wrappers.hpp:207
T value
The argument value.
Definition arg_wrappers.hpp:209
Function argument wrapper for threshold parameter.
Definition arg_wrappers.hpp:397
T value
The argument value.
Definition arg_wrappers.hpp:399