9#include "arg_wrappers.hpp"
11#include "int_arith.hpp"
12#include "introspect.hpp"
13#include "numeric_traits.hpp"
14#include "processor.hpp"
15#include "time_tagged_events.hpp"
26template <
typename NumericTraits,
typename Downstream>
27 requires processor<Downstream, time_reached_event<NumericTraits>>
28class regulate_time_reached {
29 using abstime_type = NumericTraits::abstime_type;
31 abstime_type interval_thresh;
32 std::size_t count_thresh;
34 abstime_type exact_reached = std::numeric_limits<abstime_type>::min();
35 abstime_type next_time_thresh = std::numeric_limits<abstime_type>::min();
36 std::size_t emitted_since_prev_time_reached = 0;
37 std::size_t seen_since_prev_time_reached = 0;
39 Downstream downstream;
42 void handle_time_reached(abstime_type abstime) {
43 ++seen_since_prev_time_reached;
44 if (abstime >= next_time_thresh ||
45 emitted_since_prev_time_reached >= count_thresh) {
46 downstream.handle(time_reached_event<NumericTraits>{abstime});
47 next_time_thresh = add_sat(abstime, interval_thresh);
48 emitted_since_prev_time_reached = 0;
49 seen_since_prev_time_reached = 0;
51 exact_reached = abstime;
55 explicit regulate_time_reached(
56 arg::interval_threshold<abstime_type> interval_threshold,
57 arg::count_threshold<std::size_t> count_threshold,
58 Downstream downstream)
59 : interval_thresh(interval_threshold.value),
60 count_thresh(count_threshold.value),
61 downstream(std::move(downstream)) {}
63 [[nodiscard]]
auto introspect_node() const -> processor_info {
64 return processor_info(
this,
"regulate_time_reached");
67 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
68 return downstream.introspect_graph().push_entry_point(
this);
71 template <
typename NT>
void handle(time_reached_event<NT>
const &event) {
72 static_assert(std::is_same_v<typename NT::abstime_type, abstime_type>);
73 handle_time_reached(event.abstime);
77 template <
typename NT>
void handle(time_reached_event<NT> &&event) {
78 handle(
static_cast<time_reached_event<NT>
const &
>(event));
81 template <
typename OtherEvent>
82 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
83 void handle(OtherEvent &&event) {
84 static_assert(std::is_same_v<
decltype(
event.abstime), abstime_type>);
85 auto const abstime =
event.abstime;
86 downstream.handle(std::forward<OtherEvent>(event));
87 ++emitted_since_prev_time_reached;
88 handle_time_reached(abstime);
96 if (exact_reached > std::numeric_limits<abstime_type>::min() &&
97 seen_since_prev_time_reached > 0)
99 time_reached_event<NumericTraits>{exact_reached});
168template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
173 return internal::regulate_time_reached<NumericTraits, Downstream>(
174 interval_threshold, count_threshold, std::move(downstream));
auto regulate_time_reached(arg::interval_threshold< typename NumericTraits::abstime_type > interval_threshold, arg::count_threshold< std::size_t > count_threshold, Downstream downstream)
Create a processor that regulates the frequency of time-reached events.
Definition regulate_time_reached.hpp:169
libtcspc namespace.
Definition acquire.hpp:30
Function argument wrapper for count threshold parameter.
Definition arg_wrappers.hpp:107
Function argument wrapper for interval threshold parameter.
Definition arg_wrappers.hpp:187