1 module caLib_util.Controller; 2 3 import caLib_abstract.lattice : isLattice; 4 import caLib_abstract.rule : isRule, isReversibleRule; 5 import caLib_abstract.renderer : isRenderer; 6 import derelict.sdl2.sdl; 7 import std.stdio: writeln; 8 import std.exception : Exception; 9 10 11 12 auto create_Controller(Lt, Rt, REt)(Lt* lattice, Rt* rule, REt* renderer) 13 { 14 return new Controller!(Lt, Rt, REt)(lattice, rule, renderer); 15 } 16 17 18 19 class Controller(Lt, Rt, REt) 20 { 21 22 private: 23 24 Lt* lattice; 25 Rt* rule; 26 REt* renderer; 27 28 void delegate() task; 29 bool running; 30 bool recording; 31 32 static if(isReversibleRule!Rt) 33 { 34 bool reverse; 35 } 36 37 public: 38 39 this(Lt* lattice, Rt* rule, REt* renderer) 40 { 41 this.lattice = lattice; 42 this.rule = rule; 43 this.renderer = renderer; 44 45 this.task = null; 46 this.running = false; 47 this.recording = false; 48 49 static if(isReversibleRule!Rt) 50 { 51 bool reverse = false; 52 } 53 } 54 55 void start() 56 { 57 renderer.render(); 58 59 task = &this.pause; 60 61 while(true) 62 { 63 SDL_Event events; 64 while(SDL_PollEvent(&events)) 65 { 66 if(events.type == SDL_QUIT) 67 { 68 return; 69 } 70 else if(events.type == SDL_KEYDOWN) 71 { 72 if(events.key.keysym.sym == SDLK_SPACE) 73 { 74 if(running) 75 { 76 task = &this.pause; 77 running = false; 78 } 79 else 80 { 81 task = &this.run; 82 running = true; 83 } 84 } 85 else if(events.key.keysym.sym == SDLK_d) 86 { 87 run(); 88 task = &this.pause; 89 running = false; 90 } 91 else if(events.key.keysym.sym == SDLK_s) 92 { 93 screenshot(); 94 } 95 else if(events.key.keysym.sym == SDLK_r) 96 { 97 record(); 98 } 99 static if(isReversibleRule!Rt) 100 { 101 if(events.key.keysym.sym == SDLK_a) 102 { 103 reverse = !reverse; 104 writeln("running reverse"); 105 } 106 } 107 } 108 } 109 110 task(); 111 } 112 } 113 114 void pause() {} 115 116 void run() 117 { 118 static if(isReversibleRule!Rt) 119 { 120 if(!reverse) 121 rule.applyRule(); 122 else 123 rule.applyRuleReverse(); 124 } 125 else 126 { 127 rule.applyRule(); 128 } 129 renderer.render(); 130 } 131 132 void screenshot() 133 { 134 writeln("screenshoting. The programm might seem unresponsive"); 135 try 136 { 137 renderer.screenshot("screenshot.png"); 138 writeln("done screenshoting"); 139 } 140 catch(Exception e) 141 { 142 writeln("could not screenshot. Error message:\n ", e.msg); 143 } 144 } 145 146 void record() 147 { 148 if(recording) 149 { 150 scope(exit) recording = false; 151 try 152 { 153 renderer.stopRecording(); 154 writeln("done recording"); 155 } 156 catch(Exception e) 157 { 158 writeln("could not complete recording. Error message:\n ", 159 e.msg); 160 } 161 } 162 else 163 { 164 try 165 { 166 renderer.startRecording("recording.mp4", 10); 167 writeln("recording.. Press r to stop recording"); 168 recording = true; 169 } 170 catch(Exception e) 171 { 172 writeln("could not start recording. Error message:\n ", 173 e.msg); 174 175 recording = false; 176 } 177 } 178 } 179 }