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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::sync::Arc;

use crate::command::handle_param_setters;

use super::{ClockId, ClockShared, ClockSpeed, ClockTime, CommandWriters};

/// Controls a clock.
///
/// When a [`ClockHandle`] is dropped, the corresponding clock
/// will be removed.
#[derive(Debug)]
pub struct ClockHandle {
	pub(crate) id: ClockId,
	pub(crate) shared: Arc<ClockShared>,
	pub(crate) command_writers: CommandWriters,
}

impl ClockHandle {
	/// Returns the unique identifier for the clock.
	#[must_use]
	pub fn id(&self) -> ClockId {
		self.id
	}

	/// Returns `true` if the clock is currently ticking
	/// and `false` if not.
	#[must_use]
	pub fn ticking(&self) -> bool {
		self.shared.ticking()
	}

	/// Returns the current time of the clock.
	#[must_use]
	pub fn time(&self) -> ClockTime {
		ClockTime {
			clock: self.id,
			ticks: self.shared.ticks(),
			fraction: self.shared.fractional_position(),
		}
	}

	handle_param_setters! {
		/// Sets the speed of the clock.
		speed: ClockSpeed,
	}

	/// Starts or resumes the clock.
	pub fn start(&mut self) {
		self.command_writers.set_ticking.write(true)
	}

	/// Pauses the clock.
	pub fn pause(&mut self) {
		self.command_writers.set_ticking.write(false)
	}

	/// Stops and resets the clock.
	pub fn stop(&mut self) {
		self.command_writers.set_ticking.write(false);
		self.command_writers.reset.write(());
	}
}

impl Drop for ClockHandle {
	fn drop(&mut self) {
		self.shared.mark_for_removal();
	}
}

impl From<&ClockHandle> for ClockId {
	fn from(handle: &ClockHandle) -> Self {
		handle.id()
	}
}