9#include "arg_wrappers.hpp"
11#include "data_types.hpp"
13#include "introspect.hpp"
14#include "processor.hpp"
33template <
typename DataTypes = default_data_types>
62 return stream <<
"offset_and_interval(" <<
event.abstime <<
" + "
63 <<
event.delay <<
", " <<
event.interval <<
')';
75template <
typename DataTypes = default_data_types>
96 return stream <<
"real_one_shot_timing(" <<
event.abstime <<
" + "
97 <<
event.delay <<
')';
109template <
typename DataTypes = default_data_types>
140 return stream <<
"real_linear_timing(" <<
event.abstime <<
" + "
141 <<
event.delay <<
", " <<
event.interval <<
", "
142 <<
event.count <<
')';
148template <
typename DataTypes,
typename Downstream>
151 processor<Downstream, periodic_sequence_model_event<DataTypes>>);
153 using abstime_type =
typename DataTypes::abstime_type;
155 abstime_type max_shift;
157 Downstream downstream;
160 explicit retime_periodic_sequences(
161 arg::max_time_shift<typename DataTypes::abstime_type> max_time_shift,
162 Downstream downstream)
163 : max_shift(max_time_shift.value), downstream(std::move(downstream)) {
165 throw std::invalid_argument(
166 "retime_periodic_sequences max_time_shift must not be negative");
169 [[nodiscard]]
auto introspect_node() const -> processor_info {
170 return processor_info(
this,
"retime_periodic_sequences");
173 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
174 return downstream.introspect_graph().push_entry_point(
this);
177 template <
typename DT>
178 void handle(periodic_sequence_model_event<DT>
const &event) {
179 static_assert(std::is_same_v<typename DT::abstime_type, abstime_type>);
181 auto delta = std::floor(event.delay) - 1.0;
182 if (std::abs(delta) >
static_cast<double>(max_shift))
183 throw data_validation_error(
184 "retime periodic sequence: abstime would shift more than max time shift");
186 abstime_type abstime{};
187 if constexpr (std::is_unsigned_v<abstime_type>) {
189 auto ndelta =
static_cast<abstime_type
>(-delta);
190 if (ndelta > event.abstime)
191 throw data_validation_error(
192 "retime periodic sequence: abstime would be negative but abstime_type is unsigned");
193 abstime =
event.abstime - ndelta;
195 abstime =
event.abstime +
static_cast<abstime_type
>(delta);
198 abstime =
event.abstime +
static_cast<abstime_type
>(delta);
201 downstream.handle(periodic_sequence_model_event<DataTypes>{
202 abstime,
event.delay - delta,
event.interval});
205 void flush() { downstream.flush(); }
263template <
typename DataTypes = default_data_types,
typename Downstream>
266 Downstream downstream) {
267 return internal::retime_periodic_sequences<DataTypes, Downstream>(
268 max_time_shift, std::move(downstream));
273template <
typename DataTypes,
typename Downstream>
276 processor<Downstream, real_one_shot_timing_event<DataTypes>>);
279 Downstream downstream;
282 explicit extrapolate_periodic_sequences(
283 arg::tick_index<std::size_t> tick_index, Downstream downstream)
284 : m(static_cast<double>(tick_index.value)),
285 downstream(std::move(downstream)) {}
287 [[nodiscard]]
auto introspect_node() const -> processor_info {
288 return processor_info(
this,
"extrapolate_periodic_sequences");
291 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
292 return downstream.introspect_graph().push_entry_point(
this);
295 template <
typename DT>
296 void handle(periodic_sequence_model_event<DT>
const &event) {
297 static_assert(std::is_same_v<
typename DT::abstime_type,
298 typename DataTypes::abstime_type>);
299 downstream.handle(real_one_shot_timing_event<DataTypes>{
300 event.abstime,
event.delay +
event.interval * m});
303 template <
typename DT>
305 void handle(periodic_sequence_model_event<DT> &&event) {
306 handle(
static_cast<periodic_sequence_model_event<DT>
const &
>(event));
309 template <
typename OtherEvent>
310 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
311 void handle(OtherEvent &&event) {
312 downstream.handle(std::forward<OtherEvent>(event));
315 void flush() { downstream.flush(); }
357template <
typename DataTypes = default_data_types,
typename Downstream>
359 Downstream downstream) {
360 return internal::extrapolate_periodic_sequences<DataTypes, Downstream>(
361 tick_index, std::move(downstream));
366template <
typename DataTypes,
typename Downstream>
368 static_assert(processor<Downstream, real_linear_timing_event<DataTypes>>);
371 Downstream downstream;
374 explicit add_count_to_periodic_sequences(arg::count<std::size_t>
count,
375 Downstream downstream)
376 : ct(
count.value), downstream(std::move(downstream)) {}
378 [[nodiscard]]
auto introspect_node() const -> processor_info {
379 return processor_info(
this,
"add_count_to_periodic_sequences");
382 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
383 return downstream.introspect_graph().push_entry_point(
this);
386 template <
typename DT>
387 void handle(periodic_sequence_model_event<DT>
const &event) {
388 static_assert(std::is_same_v<
typename DT::abstime_type,
389 typename DataTypes::abstime_type>);
390 downstream.handle(real_linear_timing_event<DataTypes>{
391 event.abstime,
event.delay,
event.interval, ct});
394 template <
typename DT>
396 void handle(periodic_sequence_model_event<DT> &&event) {
397 handle(
static_cast<periodic_sequence_model_event<DT>
const &
>(event));
400 template <
typename OtherEvent>
401 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
402 void handle(OtherEvent &&event) {
403 downstream.handle(std::forward<OtherEvent>(event));
406 void flush() { downstream.flush(); }
443template <
typename DataTypes = default_data_types,
typename Downstream>
445 Downstream downstream) {
446 return internal::add_count_to_periodic_sequences<DataTypes, Downstream>(
447 count, std::move(downstream));
452template <
typename TickEvent,
typename StartEvent,
typename StopEvent,
455 static_assert(processor<Downstream, StartEvent, StopEvent>);
458 std::is_same_v<decltype(std::declval<TickEvent>().abstime),
459 decltype(std::declval<StartEvent>().abstime)>);
460 static_assert(std::is_same_v<decltype(std::declval<TickEvent>().abstime),
461 decltype(std::declval<StopEvent>().abstime)>);
463 std::size_t input_len;
464 std::size_t seen = 0;
465 Downstream downstream;
468 explicit convert_sequences_to_start_stop(arg::count<std::size_t>
count,
469 Downstream downstream)
470 : input_len(
count.value + 1), downstream(std::move(downstream)) {}
472 [[nodiscard]]
auto introspect_node() const -> processor_info {
473 return processor_info(
this,
"convert_sequences_to_start_stop");
476 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
477 return downstream.introspect_graph().push_entry_point(
this);
480 void handle(TickEvent
const &event) {
483 e.abstime =
event.abstime;
484 downstream.handle(std::move(e));
487 if (seen < input_len) {
489 e.abstime =
event.abstime;
490 downstream.handle(std::move(e));
497 void handle(TickEvent &&event) {
498 handle(
static_cast<TickEvent
const &
>(event));
501 template <
typename OtherEvent>
502 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
503 void handle(OtherEvent &&event) {
504 downstream.handle(std::forward<OtherEvent>(event));
507 void flush() { downstream.flush(); }
556template <
typename TickEvent,
typename StartEvent,
typename StopEvent,
559 Downstream downstream) {
560 return internal::convert_sequences_to_start_stop<TickEvent, StartEvent,
561 StopEvent, Downstream>(
562 count, std::move(downstream));
auto count(access_tracker< count_access > &&tracker, Downstream downstream)
Create a processor that counts events of a given type.
Definition count.hpp:313
auto retime_periodic_sequences(arg::max_time_shift< typename DataTypes::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:264
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:558
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:358
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:444
libtcspc namespace.
Definition acquire.hpp:29
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 delay
The estimated time of the first event, relative to abstime.
Definition timing_misc.hpp:46
double interval
Interval, in abstime units per index, of the modeled sequence.
Definition timing_misc.hpp:51
DataTypes::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:38
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.
Event representing a prescription for linear timing generation with real (fractional) delay and inter...
Definition timing_misc.hpp:110
DataTypes::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:114
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
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
friend auto operator==(real_one_shot_timing_event const &lhs, real_one_shot_timing_event const &rhs) noexcept -> bool=default
Equality comparison operator.
DataTypes::abstime_type abstime
Absolute time of this event, used as a reference point.
Definition timing_misc.hpp:80
double delay
The time delay relative to abstime.
Definition timing_misc.hpp:85