// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #pragma once /*! \file rx-time_interval.hpp \brief Returns an observable that emits indications of the amount of time lapsed between consecutive emissions of the source observable. The first emission from this new Observable indicates the amount of time lapsed between the time when the observer subscribed to the Observable and the time when the source Observable emitted its first item. \tparam Coordination the type of the scheduler. \param coordination the scheduler for time intervals. \return Observable that emits a time_duration to indicate the amount of time lapsed between pairs of emissions. \sample \snippet time_interval.cpp time_interval sample \snippet output.txt time_interval sample */ #if !defined(RXCPP_OPERATORS_RX_TIME_INTERVAL_HPP) #define RXCPP_OPERATORS_RX_TIME_INTERVAL_HPP #include "../rx-includes.hpp" namespace rxcpp { namespace operators { namespace detail { template struct time_interval_invalid_arguments {}; template struct time_interval_invalid : public rxo::operator_base> { using type = observable, time_interval_invalid>; }; template using time_interval_invalid_t = typename time_interval_invalid::type; template struct time_interval { typedef rxu::decay_t source_value_type; typedef rxu::decay_t coordination_type; struct time_interval_values { time_interval_values(coordination_type c) : coordination(c) { } coordination_type coordination; }; time_interval_values initial; time_interval(coordination_type coordination) : initial(coordination) { } template struct time_interval_observer { typedef time_interval_observer this_type; typedef source_value_type value_type; typedef rxu::decay_t dest_type; typedef observer observer_type; typedef rxsc::scheduler::clock_type::time_point time_point; dest_type dest; coordination_type coord; mutable time_point last; time_interval_observer(dest_type d, coordination_type coordination) : dest(std::move(d)), coord(std::move(coordination)), last(coord.now()) { } void on_next(source_value_type) const { time_point now = coord.now(); dest.on_next(now - last); last = now; } void on_error(rxu::error_ptr e) const { dest.on_error(e); } void on_completed() const { dest.on_completed(); } static subscriber make(dest_type d, time_interval_values v) { return make_subscriber(d, this_type(d, v.coordination)); } }; template auto operator()(Subscriber dest) const -> decltype(time_interval_observer::make(std::move(dest), initial)) { return time_interval_observer::make(std::move(dest), initial); } }; } /*! @copydoc rx-time_interval.hpp */ template auto time_interval(AN&&... an) -> operator_factory { return operator_factory(std::make_tuple(std::forward(an)...)); } } template<> struct member_overload { template>, class SourceValue = rxu::value_type_t, class TimeInterval = rxo::detail::time_interval, class Value = typename rxsc::scheduler::clock_type::time_point::duration> static auto member(Observable&& o) -> decltype(o.template lift(TimeInterval(identity_current_thread()))) { return o.template lift(TimeInterval(identity_current_thread())); } template, is_coordination>, class SourceValue = rxu::value_type_t, class TimeInterval = rxo::detail::time_interval>, class Value = typename rxsc::scheduler::clock_type::time_point::duration> static auto member(Observable&& o, Coordination&& cn) -> decltype(o.template lift(TimeInterval(std::forward(cn)))) { return o.template lift(TimeInterval(std::forward(cn))); } template static operators::detail::time_interval_invalid_t member(AN...) { std::terminate(); return {}; static_assert(sizeof...(AN) == 10000, "time_interval takes (optional Coordination)"); } }; } #endif