timed_events.hpp 3.75 KB
Newer Older
louiz’'s avatar
louiz’ committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#ifndef TIMED_EVENTS_HPP
# define TIMED_EVENTS_HPP

#include <functional>
#include <chrono>
#include <list>

using namespace std::literals::chrono_literals;

namespace utils {
static constexpr std::chrono::milliseconds no_timeout = std::chrono::milliseconds(-1);
}

class TimedEventsManager;

/**
 * A callback with an associated date.
 */

class TimedEvent
{
  friend class TimedEventsManager;
public:
  /**
   * An event the occurs only once, at the given time_point
   */
  explicit TimedEvent(std::chrono::steady_clock::time_point&& time_point,
28
                      std::function<void()> callback, const std::string& name="");
louiz’'s avatar
louiz’ committed
29
  explicit TimedEvent(std::chrono::milliseconds&& duration,
30
                      std::function<void()> callback, const std::string& name="");
louiz’'s avatar
louiz’ committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

  explicit TimedEvent(TimedEvent&&);
  ~TimedEvent();
  /**
   * Whether or not this event happens after the other one.
   */
  bool is_after(const TimedEvent& other) const;
  bool is_after(const std::chrono::steady_clock::time_point& time_point) const;
  /**
   * Return the duration difference between now and the event time point.
   * If the difference would be negative (i.e. the event is expired), the
   * returned value is 0 instead. The value cannot then be negative.
   */
  std::chrono::milliseconds get_timeout() const;
  void execute();
46
  const std::string& get_name() const;
louiz’'s avatar
louiz’ committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

private:
  /**
   * The next time point at which the event is executed.
   */
  std::chrono::steady_clock::time_point time_point;
  /**
   * The function to execute.
   */
  const std::function<void()> callback;
  /**
   * Whether or not this events repeats itself until it is destroyed.
   */
  const bool repeat;
  /**
   * This value is added to the time_point each time the event is executed,
   * if repeat is true. Otherwise it is ignored.
   */
  const std::chrono::milliseconds repeat_delay;
66 67 68 69 70 71
  /**
   * A name that is used to identify that event. If you want to find your
   * event (for example if you want to cancel it), the name should be
   * unique.
   */
  const std::string name;
louiz’'s avatar
louiz’ committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

  TimedEvent(const TimedEvent&) = delete;
  TimedEvent& operator=(const TimedEvent&) = delete;
  TimedEvent& operator=(TimedEvent&&) = delete;
};

/**
 * A class managing a list of TimedEvents.
 * They are sorted, new events can be added, removed, fetch, etc.
 */

class TimedEventsManager
{
public:
  explicit TimedEventsManager();
  ~TimedEventsManager();
  /**
   * Add an event to the list of managed events. The list is sorted after
   * this call.
   */
  void add_event(TimedEvent&& event);
  /**
   * Returns the duration, in milliseconds, between now and the next
   * available event. If the event is already expired (the duration is
   * negative), 0 is returned instead (as in “it's not too late, execute it
   * now”)
   * Returns a negative value if no event is available.
   */
  std::chrono::milliseconds get_timeout() const;
  /**
   * Execute all the expired events (if their expiration time is exactly
   * now, or before now). The event is then removed from the list. If the
   * event does repeat, its expiration time is updated and it is reinserted
   * in the list at the correct position.
   * Returns the number of executed events.
   */
  std::size_t execute_expired_events();
109 110 111 112 113 114 115 116 117
  /**
   * Remove (and thus cancel) all the timed events with the given name.
   * Returns the number of canceled events.
   */
  std::size_t cancel(const std::string& name);
  /**
   * Return the number of managed events.
   */
  std::size_t size() const;
louiz’'s avatar
louiz’ committed
118 119 120 121 122 123 124 125 126 127

private:
  std::list<TimedEvent> events;
  TimedEventsManager(const TimedEventsManager&) = delete;
  TimedEventsManager(TimedEventsManager&&) = delete;
  TimedEventsManager& operator=(const TimedEventsManager&) = delete;
  TimedEventsManager& operator=(TimedEventsManager&&) = delete;
};

#endif // TIMED_EVENTS_HPP