9#include "arg_wrappers.hpp"
11#include "data_types.hpp"
12#include "introspect.hpp"
13#include "processor.hpp"
25template <
typename TriggerEvent,
typename OutputEvent,
26 typename TimingGenerator,
typename Downstream>
28 static_assert(processor<Downstream, TriggerEvent, OutputEvent>);
30 using abstime_type =
decltype(std::declval<TriggerEvent>().abstime);
32 std::is_same_v<std::remove_reference_t<
33 decltype(*std::declval<TimingGenerator>().peek())>,
35 static_assert(std::is_same_v<decltype(std::declval<OutputEvent>().abstime),
38 TimingGenerator generator;
40 Downstream downstream;
43 template <
typename Pred>
void emit(Pred predicate) {
44 auto const &const_gen = generator;
45 for (std::optional<abstime_type> t = const_gen.peek();
46 t && predicate(*t); t = const_gen.peek()) {
50 downstream.handle(std::move(event));
55 explicit generate(TimingGenerator generator, Downstream downstream)
56 : generator(std::move(generator)), downstream(std::move(downstream)) {}
58 [[nodiscard]]
auto introspect_node() const -> processor_info {
59 return processor_info(
this,
"generate");
62 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
63 return downstream.introspect_graph().push_entry_point(
this);
67 requires handler_for<Downstream, std::remove_cvref_t<E>>
68 void handle(E &&event) {
69 emit([now = event.abstime](
auto t) { return t <= now; });
70 if constexpr (std::is_convertible_v<std::remove_cvref_t<E>,
72 generator.trigger(event);
74 downstream.handle(std::forward<E>(event));
137template <
typename TriggerEvent,
typename OutputEvent,
138 typename TimingGenerator,
typename Downstream>
139auto generate(TimingGenerator generator, Downstream downstream) {
140 return internal::generate<TriggerEvent, OutputEvent, TimingGenerator,
141 Downstream>(std::move(generator),
142 std::move(downstream));
152template <
typename DataTypes = default_data_types>
156 template <
typename TriggerEvent>
void trigger(TriggerEvent
const &event) {
157 static_assert(std::is_same_v<
decltype(
event.abstime),
158 typename DataTypes::abstime_type>);
162 [[nodiscard]]
auto peek() const
163 -> std::optional<typename DataTypes::abstime_type> {
168 void pop() { internal::unreachable(); }
178template <
typename DataTypes = default_data_types>
180 std::optional<typename DataTypes::abstime_type> next;
181 typename DataTypes::abstime_type dly;
194 throw std::invalid_argument(
195 "one_shot_timing_generator delay must not be negative");
199 template <
typename TriggerEvent>
void trigger(TriggerEvent
const &event) {
200 static_assert(std::is_same_v<
decltype(
event.abstime),
201 typename DataTypes::abstime_type>);
202 next =
event.abstime + dly;
206 [[nodiscard]]
auto peek() const
207 -> std::optional<typename DataTypes::abstime_type> {
212 void pop() { next.reset(); }
226template <
typename DataTypes = default_data_types>
228 std::optional<typename DataTypes::abstime_type> next;
232 template <
typename TriggerEvent>
void trigger(TriggerEvent
const &event) {
233 static_assert(std::is_same_v<
decltype(
event.abstime),
234 typename DataTypes::abstime_type>);
235 static_assert(std::is_same_v<
decltype(
event.delay),
236 typename DataTypes::abstime_type>);
237 next =
event.abstime +
event.delay;
241 [[nodiscard]]
auto peek() const
242 -> std::optional<typename DataTypes::abstime_type> {
247 void pop() { next.reset(); }
257template <
typename DataTypes = default_data_types>
259 typename DataTypes::abstime_type next = 0;
260 std::size_t remaining = 0;
262 typename DataTypes::abstime_type dly;
263 typename DataTypes::abstime_type intval;
277 : dly(
delay.value), intval(interval.value), ct(
count.value) {
279 throw std::invalid_argument(
280 "linear_timing_generator delay must not be negative");
282 throw std::invalid_argument(
283 "linear_timing_generator interval must be positive");
287 template <
typename TriggerEvent>
void trigger(TriggerEvent
const &event) {
288 static_assert(std::is_same_v<
decltype(
event.abstime),
289 typename DataTypes::abstime_type>);
290 next =
event.abstime + dly;
295 [[nodiscard]]
auto peek() const
296 -> std::optional<typename DataTypes::abstime_type> {
320template <
typename DataTypes = default_data_types>
322 typename DataTypes::abstime_type next = 0;
323 std::size_t remaining = 0;
324 typename DataTypes::abstime_type interval = 0;
328 template <
typename TriggerEvent>
void trigger(TriggerEvent
const &event) {
329 static_assert(std::is_same_v<
decltype(
event.abstime),
330 typename DataTypes::abstime_type>);
331 next =
event.abstime +
event.delay;
332 remaining =
event.count;
333 interval =
event.interval;
337 [[nodiscard]]
auto peek() const
338 -> std::optional<typename DataTypes::abstime_type> {
Timing generator that generates an equally spaced series of timings, configured by the trigger event.
Definition generate.hpp:321
auto peek() const -> std::optional< typename DataTypes::abstime_type >
Implements timing generator requirement.
Definition generate.hpp:337
void pop()
Implements timing generator requirement.
Definition generate.hpp:345
void trigger(TriggerEvent const &event)
Implements timing generator requirement.
Definition generate.hpp:328
Timing generator that generates a single, delayed timing, configured by the trigger event.
Definition generate.hpp:227
void trigger(TriggerEvent const &event)
Implements timing generator requirement.
Definition generate.hpp:232
auto peek() const -> std::optional< typename DataTypes::abstime_type >
Implements timing generator requirement.
Definition generate.hpp:241
void pop()
Implements timing generator requirement.
Definition generate.hpp:247
void pop()
Implements timing generator requirement.
Definition generate.hpp:303
auto peek() const -> std::optional< typename DataTypes::abstime_type >
Implements timing generator requirement.
Definition generate.hpp:295
linear_timing_generator(arg::delay< typename DataTypes::abstime_type > delay, arg::interval< typename DataTypes::abstime_type > interval, arg::count< std::size_t > count)
Construct an instance that generates count timings at interval after delay relative to each trigger.
Definition generate.hpp:273
void trigger(TriggerEvent const &event)
Implements timing generator requirement.
Definition generate.hpp:287
Timing generator that generates no timings.
Definition generate.hpp:153
void trigger(TriggerEvent const &event)
Implements timing generator requirement.
Definition generate.hpp:156
auto peek() const -> std::optional< typename DataTypes::abstime_type >
Implements timing generator requirement.
Definition generate.hpp:162
void pop()
Implements timing generator requirement.
Definition generate.hpp:168
void pop()
Implements timing generator requirement.
Definition generate.hpp:212
void trigger(TriggerEvent const &event)
Implements timing generator requirement.
Definition generate.hpp:199
auto peek() const -> std::optional< typename DataTypes::abstime_type >
Implements timing generator requirement.
Definition generate.hpp:206
one_shot_timing_generator(arg::delay< typename DataTypes::abstime_type > delay)
Construct an instance that generates a timing after delay relative to each trigger.
Definition generate.hpp:190
auto count(access_tracker< count_access > &&tracker, Downstream downstream)
Create a processor that counts events of a given type.
Definition count.hpp:313
auto delay(arg::delta< typename DataTypes::abstime_type > delta, Downstream downstream)
Create a processor that applies an abstime offset to all events.
Definition delay.hpp:123
auto generate(TimingGenerator generator, Downstream downstream)
Create a processor that generates a pattern of timing events in response to a trigger.
Definition generate.hpp:139
libtcspc namespace.
Definition acquire.hpp:29
Function argument wrapper for count parameter.
Definition arg_wrappers.hpp:97
Function argument wrapper for delay parameter.
Definition arg_wrappers.hpp:117
Function argument wrapper for interval parameter.
Definition arg_wrappers.hpp:177