libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
regulate_time_reached.hpp
1/*
2 * This file is part of libtcspc
3 * Copyright 2019-2026 Board of Regents of the University of Wisconsin System
4 * SPDX-License-Identifier: MIT
5 */
6
7#pragma once
8
9#include "arg_wrappers.hpp"
10#include "common.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"
16
17#include <cstddef>
18#include <limits>
19#include <type_traits>
20#include <utility>
21
22namespace tcspc {
23
24namespace internal {
25
26template <typename NumericTraits, typename Downstream>
27 requires processor<Downstream, time_reached_event<NumericTraits>>
28class regulate_time_reached {
29 using abstime_type = NumericTraits::abstime_type;
30
31 abstime_type interval_thresh;
32 std::size_t count_thresh;
33
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;
38
39 Downstream downstream;
40
41 // Called for all upstream times seen.
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;
50 }
51 exact_reached = abstime;
52 }
53
54 public:
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)) {}
62
63 [[nodiscard]] auto introspect_node() const -> processor_info {
64 return processor_info(this, "regulate_time_reached");
65 }
66
67 [[nodiscard]] auto introspect_graph() const -> processor_graph {
68 return downstream.introspect_graph().push_entry_point(this);
69 }
70
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);
74 }
75
76 // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
77 template <typename NT> void handle(time_reached_event<NT> &&event) {
78 handle(static_cast<time_reached_event<NT> const &>(event));
79 }
80
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);
89 }
90
91 void flush() {
92 // Emit time-reached for last seen event in order to convey the (best
93 // known) stream end time on all downstream paths.
94 // Only do so if we received at least one event and the last emitted
95 // was something other than time-reached.
96 if (exact_reached > std::numeric_limits<abstime_type>::min() &&
97 seen_since_prev_time_reached > 0)
98 downstream.handle(
99 time_reached_event<NumericTraits>{exact_reached});
100 downstream.flush();
101 }
102};
103
104} // namespace internal
105
168template <typename NumericTraits = default_numeric_traits, typename Downstream>
171 interval_threshold,
172 arg::count_threshold<std::size_t> count_threshold, Downstream downstream) {
173 return internal::regulate_time_reached<NumericTraits, Downstream>(
174 interval_threshold, count_threshold, std::move(downstream));
175}
176
177} // namespace tcspc
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