9#include "arg_wrappers.hpp"
12#include "introspect.hpp"
13#include "numeric_traits.hpp"
14#include "processor.hpp"
33template <
typename NumericTraits = default_numeric_traits>
62 return stream <<
"offset_and_interval(" <<
event.abstime <<
" + "
63 <<
event.delay <<
", " <<
event.interval <<
')';
75template <
typename NumericTraits = default_numeric_traits>
96 return stream <<
"real_one_shot_timing(" <<
event.abstime <<
" + "
97 <<
event.delay <<
')';
109template <
typename NumericTraits = default_numeric_traits>
140 return stream <<
"real_linear_timing(" <<
event.abstime <<
" + "
141 <<
event.delay <<
", " <<
event.interval <<
", "
142 <<
event.count <<
')';
148template <
typename NumericTraits,
typename Downstream>
151 processor<Downstream, periodic_sequence_model_event<NumericTraits>>);
153 using abstime_type = NumericTraits::abstime_type;
155 abstime_type max_shift;
157 Downstream downstream;
160 explicit retime_periodic_sequences(
161 arg::max_time_shift<typename NumericTraits::abstime_type>
163 Downstream downstream)
164 : max_shift(max_time_shift.value), downstream(std::move(downstream)) {
166 throw std::invalid_argument(
167 "retime_periodic_sequences max_time_shift must not be negative");
170 [[nodiscard]]
auto introspect_node() const -> processor_info {
171 return processor_info(
this,
"retime_periodic_sequences");
174 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
175 return downstream.introspect_graph().push_entry_point(
this);
178 template <
typename NT>
179 void handle(periodic_sequence_model_event<NT>
const &event) {
180 static_assert(std::is_same_v<typename NT::abstime_type, abstime_type>);
182 auto delta = std::floor(event.delay) - 1.0;
183 if (std::abs(delta) >
static_cast<double>(max_shift))
184 throw data_validation_error(
185 "retime periodic sequence: abstime would shift more than max time shift");
187 abstime_type abstime{};
188 if constexpr (std::is_unsigned_v<abstime_type>) {
190 auto ndelta =
static_cast<abstime_type
>(-delta);
191 if (ndelta > event.abstime)
192 throw data_validation_error(
193 "retime periodic sequence: abstime would be negative but abstime_type is unsigned");
194 abstime =
event.abstime - ndelta;
196 abstime =
event.abstime +
static_cast<abstime_type
>(delta);
199 abstime =
event.abstime +
static_cast<abstime_type
>(delta);
202 downstream.handle(periodic_sequence_model_event<NumericTraits>{
203 abstime,
event.delay - delta,
event.interval});
206 void flush() { downstream.flush(); }
265template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
268 Downstream downstream) {
269 return internal::retime_periodic_sequences<NumericTraits, Downstream>(
270 max_time_shift, std::move(downstream));
275template <
typename NumericTraits,
typename Downstream>
278 processor<Downstream, real_one_shot_timing_event<NumericTraits>>);
281 Downstream downstream;
284 explicit extrapolate_periodic_sequences(
285 arg::tick_index<std::size_t> tick_index, Downstream downstream)
286 : m(static_cast<double>(tick_index.value)),
287 downstream(std::move(downstream)) {}
289 [[nodiscard]]
auto introspect_node() const -> processor_info {
290 return processor_info(
this,
"extrapolate_periodic_sequences");
293 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
294 return downstream.introspect_graph().push_entry_point(
this);
297 template <
typename NT>
298 void handle(periodic_sequence_model_event<NT>
const &event) {
299 static_assert(std::is_same_v<
typename NT::abstime_type,
300 typename NumericTraits::abstime_type>);
301 downstream.handle(real_one_shot_timing_event<NumericTraits>{
302 event.abstime,
event.delay +
event.interval * m});
305 template <
typename NT>
307 void handle(periodic_sequence_model_event<NT> &&event) {
308 handle(
static_cast<periodic_sequence_model_event<NT>
const &
>(event));
311 template <
typename OtherEvent>
312 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
313 void handle(OtherEvent &&event) {
314 downstream.handle(std::forward<OtherEvent>(event));
317 void flush() { downstream.flush(); }
360template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
362 Downstream downstream) {
363 return internal::extrapolate_periodic_sequences<NumericTraits, Downstream>(
364 tick_index, std::move(downstream));
369template <
typename NumericTraits,
typename Downstream>
370 requires processor<Downstream, real_linear_timing_event<NumericTraits>>
373 Downstream downstream;
376 explicit add_count_to_periodic_sequences(arg::count<std::size_t>
count,
377 Downstream downstream)
378 : ct(
count.value), downstream(std::move(downstream)) {}
380 [[nodiscard]]
auto introspect_node() const -> processor_info {
381 return processor_info(
this,
"add_count_to_periodic_sequences");
384 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
385 return downstream.introspect_graph().push_entry_point(
this);
388 template <
typename NT>
389 void handle(periodic_sequence_model_event<NT>
const &event) {
390 static_assert(std::is_same_v<
typename NT::abstime_type,
391 typename NumericTraits::abstime_type>);
392 downstream.handle(real_linear_timing_event<NumericTraits>{
393 event.abstime,
event.delay,
event.interval, ct});
396 template <
typename NT>
398 void handle(periodic_sequence_model_event<NT> &&event) {
399 handle(
static_cast<periodic_sequence_model_event<NT>
const &
>(event));
402 template <
typename OtherEvent>
403 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
404 void handle(OtherEvent &&event) {
405 downstream.handle(std::forward<OtherEvent>(event));
408 void flush() { downstream.flush(); }
446template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
448 Downstream downstream) {
449 return internal::add_count_to_periodic_sequences<NumericTraits,
451 count, std::move(downstream));
456template <
typename TickEvent,
typename StartEvent,
typename StopEvent,
458 requires processor<Downstream, StartEvent, StopEvent>
461 std::is_same_v<decltype(std::declval<TickEvent>().abstime),
462 decltype(std::declval<StartEvent>().abstime)>);
463 static_assert(std::is_same_v<decltype(std::declval<TickEvent>().abstime),
464 decltype(std::declval<StopEvent>().abstime)>);
466 std::size_t input_len;
467 std::size_t seen = 0;
468 Downstream downstream;
471 explicit convert_sequences_to_start_stop(arg::count<std::size_t>
count,
472 Downstream downstream)
473 : input_len(
count.value + 1), downstream(std::move(downstream)) {}
475 [[nodiscard]]
auto introspect_node() const -> processor_info {
476 return processor_info(
this,
"convert_sequences_to_start_stop");
479 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
480 return downstream.introspect_graph().push_entry_point(
this);
483 void handle(TickEvent
const &event) {
486 e.abstime =
event.abstime;
487 downstream.handle(std::move(e));
490 if (seen < input_len) {
492 e.abstime =
event.abstime;
493 downstream.handle(std::move(e));
500 void handle(TickEvent &&event) {
501 handle(
static_cast<TickEvent
const &
>(event));
504 template <
typename OtherEvent>
505 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
506 void handle(OtherEvent &&event) {
507 downstream.handle(std::forward<OtherEvent>(event));
510 void flush() { downstream.flush(); }
559template <
typename TickEvent,
typename StartEvent,
typename StopEvent,
562 Downstream downstream) {
563 return internal::convert_sequences_to_start_stop<TickEvent, StartEvent,
564 StopEvent, Downstream>(
565 count, std::move(downstream));
auto count(access_tracker< count_accessor > &&tracker, Downstream downstream)
Create a processor that counts events of a given type.
Definition count.hpp:312
auto convert_sequences_to_start_stop(arg::count< std::size_t > count, Downstream downstream)
Create a processor that converts sequences of ticks to sequences of start-stop event pairs with no ga...
Definition timing_misc.hpp:561
auto extrapolate_periodic_sequences(arg::tick_index< std::size_t > tick_index, Downstream downstream)
Create a processor that emits an extrapolated one-shot timing event based on tcspc::periodic_sequence...
Definition timing_misc.hpp:361
auto add_count_to_periodic_sequences(arg::count< std::size_t > count, Downstream downstream)
Create a processor that emits a linear timing event based on tcspc::periodic_sequence_model_event by ...
Definition timing_misc.hpp:447
auto retime_periodic_sequences(arg::max_time_shift< typename NumericTraits::abstime_type > max_time_shift, Downstream downstream)
Create a processor that adjusts the abstime of tcspc::periodic_sequence_model_event to be earlier tha...
Definition timing_misc.hpp:266
libtcspc namespace.
Definition acquire.hpp:30
Function argument wrapper for count parameter.
Definition arg_wrappers.hpp:97
Function argument wrapper for maximum time shift parameter.
Definition arg_wrappers.hpp:307
Function argument wrapper for tick index parameter.
Definition arg_wrappers.hpp:407
Event representing a summarized model of a periodic sequence of events.
Definition timing_misc.hpp:34
double interval
Interval, in abstime units per index, of the modeled sequence.
Definition timing_misc.hpp:51
double delay
The estimated time of the first event, relative to abstime.
Definition timing_misc.hpp:46
friend auto operator<<(std::ostream &stream, periodic_sequence_model_event const &event) -> std::ostream &
Stream insertion operator.
Definition timing_misc.hpp:59
friend auto operator==(periodic_sequence_model_event const &lhs, periodic_sequence_model_event const &rhs) noexcept -> bool=default
Equality comparison operator.
NumericTraits::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:38
Event representing a prescription for linear timing generation with real (fractional) delay and inter...
Definition timing_misc.hpp:110
double delay
The time delay relative to abstime.
Definition timing_misc.hpp:119
friend auto operator==(real_linear_timing_event const &lhs, real_linear_timing_event const &rhs) noexcept -> bool=default
Equality comparison operator.
friend auto operator<<(std::ostream &stream, real_linear_timing_event const &event) -> std::ostream &
Stream insertion operator.
Definition timing_misc.hpp:137
double interval
Interval between the events in the represented sequence.
Definition timing_misc.hpp:124
std::size_t count
Number of events in the represented sequence.
Definition timing_misc.hpp:129
NumericTraits::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:114
Event representing a prescription for one-shot timing generation with real (fractional) delay.
Definition timing_misc.hpp:76
friend auto operator<<(std::ostream &stream, real_one_shot_timing_event const &event) -> std::ostream &
Stream insertion operator.
Definition timing_misc.hpp:93
double delay
The time delay relative to abstime.
Definition timing_misc.hpp:85
friend auto operator==(real_one_shot_timing_event const &lhs, real_one_shot_timing_event const &rhs) noexcept -> bool=default
Equality comparison operator.
NumericTraits::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:80