2016-07-29 11:15:46 +00:00
|
|
|
//
|
|
|
|
// TimedEventLoop.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 29/07/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef TimedEventLoop_hpp
|
|
|
|
#define TimedEventLoop_hpp
|
|
|
|
|
|
|
|
#include "Storage.hpp"
|
|
|
|
|
2017-07-26 00:20:55 +00:00
|
|
|
#include "../ClockReceiver/ClockReceiver.hpp"
|
2016-07-29 11:15:46 +00:00
|
|
|
#include "../SignalProcessing/Stepper.hpp"
|
2017-07-26 00:20:55 +00:00
|
|
|
|
|
|
|
#include <memory>
|
2016-07-29 11:15:46 +00:00
|
|
|
|
|
|
|
namespace Storage {
|
|
|
|
|
2016-08-01 10:04:55 +00:00
|
|
|
/*!
|
|
|
|
Provides a mechanism for arbitrarily timed events to be processed according to a fixed-base
|
|
|
|
discrete clock signal, ensuring correct timing.
|
|
|
|
|
|
|
|
Subclasses are responsible for calling @c set_next_event_time_interval to establish the time
|
|
|
|
until a next event; @c process_next_event will be called when that event occurs, with progression
|
2017-07-25 01:51:22 +00:00
|
|
|
determined via @c run_for.
|
2016-08-01 10:04:55 +00:00
|
|
|
|
|
|
|
Due to the aggregation of total timing information between events — e.g. if an event loop has
|
|
|
|
a clock rate of 1000 ticks per second and a steady stream of events that occur 10,000 times a second,
|
|
|
|
bookkeeping is necessary to ensure that 10 events are triggered per tick — subclasses should call
|
|
|
|
@c reset_timer if there is a discontinuity in events.
|
|
|
|
|
|
|
|
Subclasses may also call @c jump_to_next_event to cause the next event to be communicated instantly.
|
|
|
|
|
|
|
|
Subclasses are therefore expected to call @c set_next_event_time_interval upon obtaining an event stream,
|
|
|
|
and again in response to each call to @c process_next_event while events are ongoing. They may use
|
|
|
|
@c reset_timer to initiate a distinctly-timed stream or @c jump_to_next_event to short-circuit the timing
|
|
|
|
loop and fast forward immediately to the next event.
|
|
|
|
*/
|
2017-07-25 01:19:05 +00:00
|
|
|
class TimedEventLoop: public ClockReceiver<TimedEventLoop> {
|
2016-07-29 11:15:46 +00:00
|
|
|
public:
|
2016-08-01 10:04:55 +00:00
|
|
|
/*!
|
|
|
|
Constructs a timed event loop that will be clocked at @c input_clock_rate.
|
|
|
|
*/
|
2016-07-29 11:15:46 +00:00
|
|
|
TimedEventLoop(unsigned int input_clock_rate);
|
2016-08-01 10:04:55 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Advances the event loop by @c number_of_cycles cycles.
|
|
|
|
*/
|
2017-07-25 01:19:05 +00:00
|
|
|
void run_for(const Cycles &cycles);
|
2017-07-26 00:01:30 +00:00
|
|
|
using ClockReceiver<TimedEventLoop>::run_for;
|
2016-07-29 11:15:46 +00:00
|
|
|
|
2016-09-18 14:30:52 +00:00
|
|
|
/*!
|
|
|
|
@returns the number of whole cycles remaining until the next event is triggered.
|
|
|
|
*/
|
2016-09-17 23:52:27 +00:00
|
|
|
unsigned int get_cycles_until_next_event();
|
|
|
|
|
2016-07-29 11:15:46 +00:00
|
|
|
protected:
|
2016-08-01 10:04:55 +00:00
|
|
|
/*!
|
|
|
|
Sets the time interval, as a proportion of a second, until the next event should be triggered.
|
|
|
|
*/
|
2016-07-29 11:15:46 +00:00
|
|
|
void set_next_event_time_interval(Time interval);
|
|
|
|
|
2016-08-01 10:04:55 +00:00
|
|
|
/*!
|
|
|
|
Communicates that the next event is triggered. A subclass will idiomatically process that event
|
|
|
|
and make a fresh call to @c set_next_event_time_interval to keep the event loop running.
|
|
|
|
*/
|
2016-07-29 11:15:46 +00:00
|
|
|
virtual void process_next_event() = 0;
|
|
|
|
|
2016-08-01 10:04:55 +00:00
|
|
|
/*!
|
|
|
|
Resets timing, throwing away any current internal state. So clears any fractional ticks
|
|
|
|
that the event loop is currently tracking.
|
|
|
|
*/
|
|
|
|
void reset_timer();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Causes an immediate call to @c process_next_event and a call to @c reset_timer with the
|
|
|
|
net effect of processing the current event immediately and fast forwarding exactly to the
|
|
|
|
start of the interval prior to the next event.
|
|
|
|
*/
|
|
|
|
void jump_to_next_event();
|
|
|
|
|
2016-08-03 11:49:00 +00:00
|
|
|
/*!
|
|
|
|
@returns the amount of time that has passed since the last call to @c set_next_time_interval,
|
|
|
|
which will always be less than or equal to the time that was supplied to @c set_next_time_interval.
|
|
|
|
*/
|
|
|
|
Time get_time_into_next_event();
|
|
|
|
|
2016-07-29 11:15:46 +00:00
|
|
|
private:
|
2016-12-03 16:59:28 +00:00
|
|
|
unsigned int input_clock_rate_;
|
|
|
|
int cycles_until_event_;
|
|
|
|
Time subcycles_until_event_;
|
2016-07-29 11:15:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* TimedEventLoop_hpp */
|