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