1 module music_player;
2 
3 import cushion;
4 import std.datetime.stopwatch;
5 
6 @safe unittest
7 {
8 	// Programs to be driven by STM
9 	string status = "stopped";
10 	StopWatch playTime;
11 	void startMusic() { playTime.start(); status = "playing"; }
12 	void stopMusic()  { playTime.stop();  status = "stopped"; }
13 	void resetMusic() { playTime.reset(); }
14 	
15 	// Create StateTransitor instance
16 	struct Policy
17 	{
18 		enum string name        = "MusicPlayer";
19 		enum string stateKey    = "#>";
20 	}
21 	auto stm = createStm!(Policy, startMusic, stopMusic, resetMusic);
22 	
23 	// Initial state is "stop" that most left state.
24 	assert(stm.currentState == stm.State.stop);
25 	assert(stm.getStateName(stm.currentState) == "#>stop");
26 	assert(stm.getEventName(stm.Event.onStart) == "onStart");
27 	assert(status == "stopped");
28 	
29 	// onStart event / transit to the "#>play" state
30 	stm.put(stm.Event.onStart);
31 	assert(stm.currentState == stm.State.play);
32 	assert(playTime.running);
33 	() @trusted { import core.thread: Thread, msecs; Thread.sleep(10.msecs); }(); // progress in playing...
34 	assert(playTime.peek != 0.msecs);
35 	assert(status == "playing");
36 	
37 	// onStart event / transit to the "#>pause" state
38 	stm.put(stm.Event.onStart);
39 	assert(stm.currentState == stm.State.pause);
40 	assert(!playTime.running);
41 	assert(status == "stopped");
42 	
43 	// onStop event / transit to the "#>stop" state
44 	stm.put(stm.Event.onStop);
45 	assert(stm.currentState == stm.State.stop);
46 	assert(!playTime.running);
47 	() @trusted { import core.thread: Thread, msecs; Thread.sleep(10.msecs); }(); // progress in stopped...
48 	assert(playTime.peek == 0.msecs);
49 }
50 
51 
52 
53 @safe unittest
54 {
55 	// Programs to be driven by STM
56 	string status = "stopped";
57 	StopWatch playTime;
58 	void startMusic() { playTime.start(); status = "playing"; }
59 	void stopMusic()  { playTime.stop();  status = "stopped"; }
60 	void resetMusic() { playTime.reset(); }
61 	void delay(uint tim) @trusted
62 	{
63 		import core.thread: Thread, msecs;
64 		Thread.sleep(tim.msecs);
65 	}
66 
67 	// Create StateTransitor instance
68 	mixin(decodeStmFromCsv(import("MusicPlayer.stm.csv"),
69 	                       import("MusicPlayer.map.csv"),
70 	                       "MusicPlayer.stm.csv",
71 	                       "MusicPlayer.map.csv",
72 	                       "#>",
73 	                       "makeStm"));
74 	auto stm = makeStm();
75 
76 	// Initial state is "stop" that most left state.
77 	assert(stm.currentState == stm.State.stop);
78 	assert(stm.getStateName(stm.currentState) == "#>stop");
79 	assert(stm.getEventName(stm.Event.onStart) == "onStart");
80 	assert(status == "stopped");
81 
82 	// onStart event / transit to the "#>play" state
83 	stm.put(stm.Event.onStart);
84 	assert(stm.currentState == stm.State.play);
85 	assert(playTime.running);
86 	delay(10); // progress in playing...
87 	assert(playTime.peek != 0.msecs);
88 	assert(status == "playing");
89 
90 	// onStart event / transit to the "#>pause" state
91 	stm.put(stm.Event.onStart);
92 	assert(stm.currentState == stm.State.pause);
93 	assert(!playTime.running);
94 	assert(status == "stopped");
95 
96 	// onStop event / transit to the "#>stop" state
97 	stm.put(stm.Event.onStop);
98 	assert(stm.currentState == stm.State.stop);
99 	assert(!playTime.running);
100 	delay(10); // progress in stopped...
101 	assert(playTime.peek == 0.msecs);
102 }