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 }