PeriodClock.hxx 3.39 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2021 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef MPD_PERIOD_CLOCK_HXX
#define MPD_PERIOD_CLOCK_HXX

23
#include <chrono>
24 25 26 27 28 29

/**
 * This is a stopwatch which saves the timestamp of an event, and can
 * check whether a specified time span has passed since then.
 */
class PeriodClock {
30 31 32 33
public:
	typedef std::chrono::steady_clock::duration Duration;
	typedef Duration Delta;
	typedef std::chrono::steady_clock::time_point Stamp;
34 35

private:
36
	Stamp last;
37 38

public:
39 40 41 42 43 44 45
	/**
	 * Initializes the object, setting the last time stamp to "0",
	 * i.e. a Check() will always succeed.  If you do not want this
	 * default behaviour, call Update() immediately after creating the
	 * object.
	 */
	constexpr
46
	PeriodClock():last() {}
47 48

protected:
49
	static Stamp GetNow() {
50
		return std::chrono::steady_clock::now();
51
	}
52

53 54 55 56
	constexpr Delta Elapsed(Stamp now) const {
		return last == Stamp()
			? Delta(-1)
			: Delta(now - last);
57
	}
58

59
	constexpr bool Check(Stamp now, Duration duration) const {
60 61
		return now >= last + duration;
	}
62

63 64 65
	void Update(Stamp now) {
		last = now;
	}
66 67

public:
68
	constexpr bool IsDefined() const {
69
		return last > Stamp();
70 71 72 73 74 75
	}

	/**
	 * Resets the clock.
	 */
	void Reset() {
76
		last = Stamp();
77 78 79
	}

	/**
80 81
	 * Returns the time elapsed since the last update().  Returns
	 * a negative value if update() was never called.
82
	 */
83
	Delta Elapsed() const {
84 85 86 87 88 89
		return Elapsed(GetNow());
	}

	/**
	 * Combines a call to Elapsed() and Update().
	 */
90
	Delta ElapsedUpdate() {
91
		const auto now = GetNow();
92
		const auto result = Elapsed(now);
93 94 95 96 97 98 99 100
		Update(now);
		return result;
	}

	/**
	 * Checks whether the specified duration has passed since the last
	 * update.
	 *
101
	 * @param duration the duration
102
	 */
103
	bool Check(Duration duration) const {
104 105 106 107 108 109 110 111 112 113 114 115 116 117
		return Check(GetNow(), duration);
	}

	/**
	 * Updates the time stamp, setting it to the current clock.
	 */
	void Update() {
		Update(GetNow());
	}

	/**
	 * Updates the time stamp, setting it to the current clock plus the
	 * specified offset.
	 */
118
	void UpdateWithOffset(Delta offset) {
119 120 121 122 123 124 125 126 127
		Update(GetNow() + offset);
	}

	/**
	 * Checks whether the specified duration has passed since the last
	 * update.  If yes, it updates the time stamp.
	 *
	 * @param duration the duration in milliseconds
	 */
128
	bool CheckUpdate(Duration duration) {
129 130 131 132 133 134 135 136 137 138 139 140 141 142
		Stamp now = GetNow();
		if (Check(now, duration)) {
			Update(now);
			return true;
		} else
			return false;
	}

	/**
	 * Checks whether the specified duration has passed since the last
	 * update.  After that, it updates the time stamp.
	 *
	 * @param duration the duration in milliseconds
	 */
143
	bool CheckAlwaysUpdate(Duration duration) {
144 145 146 147 148
		Stamp now = GetNow();
		bool ret = Check(now, duration);
		Update(now);
		return ret;
	}
149 150 151
};

#endif