rt300@8
|
1 //
|
rt300@8
|
2 // SearchMessageOrganiser.h
|
rt300@8
|
3 // riftathon
|
rt300@8
|
4 //
|
rt300@8
|
5 // Created by Robert Tubb on 17/10/2014.
|
rt300@8
|
6 //
|
rt300@8
|
7 //
|
rt300@8
|
8
|
rt300@8
|
9 #ifndef __riftathon__SearchMessageOrganiser__
|
rt300@8
|
10 #define __riftathon__SearchMessageOrganiser__
|
rt300@8
|
11
|
rt300@8
|
12 #include <iostream>
|
rt300@8
|
13 #include "MessageOrganiser.h"
|
rt300@8
|
14
|
rt300@8
|
15 class SearchMessageOrganiser : public MessageOrganiser {
|
rt300@8
|
16
|
rt300@8
|
17 public:
|
rt300@8
|
18 void init( PDSynthWrapper& cs, PDSynthWrapper& ts){
|
rt300@8
|
19
|
rt300@8
|
20 testController = new TestController;
|
rt300@8
|
21
|
rt300@8
|
22 MessageOrganiser::init(cs,ts);
|
rt300@9
|
23
|
rt300@8
|
24 currentSoundPlayTimer = -1;
|
rt300@8
|
25 okToGetLeapMidi = false;
|
rt300@8
|
26
|
rt300@8
|
27 alternationSpeed = 200;
|
rt300@8
|
28
|
rt300@8
|
29 candidateSynth.setNoteLength(alternationSpeed);
|
rt300@8
|
30 targetSynth.setNoteLength(alternationSpeed);
|
rt300@8
|
31
|
rt300@8
|
32 playingAlternating = false;
|
rt300@8
|
33
|
rt300@8
|
34
|
rt300@8
|
35 verdBig.loadFont("verdana.ttf", 18, true, true);
|
rt300@8
|
36 verdBig.setLineHeight(18.0f);
|
rt300@8
|
37 verdBig.setLetterSpacing(1.037);
|
rt300@8
|
38 };
|
rt300@8
|
39
|
rt300@8
|
40 //------------------------------------------------------------------------
|
rt300@8
|
41 void drawScore(){
|
rt300@8
|
42 ofColor txtCol = ofColor(150,235,200,255);
|
rt300@8
|
43
|
rt300@8
|
44 int score = getScore();
|
rt300@8
|
45 stringstream msg;
|
rt300@8
|
46
|
rt300@8
|
47 msg << "Test: " << testController->getCurrentTestLetter();
|
rt300@8
|
48 ofSetColor(txtCol);
|
rt300@8
|
49 verdBig.drawString(msg.str(), 40, 140);
|
rt300@8
|
50 msg.str(std::string());
|
rt300@8
|
51
|
rt300@8
|
52 msg << "Score: " << score;
|
rt300@8
|
53 verdBig.drawString(msg.str(), 240, 140);
|
rt300@8
|
54 msg.str(std::string());
|
rt300@8
|
55
|
rt300@8
|
56 pair<int,int> time;
|
rt300@8
|
57 time = getTime();
|
rt300@8
|
58 msg << "Time taken: " << time.first << ":" << time.second << endl;
|
rt300@8
|
59 verdBig.drawString(msg.str(), 600, 140);
|
rt300@8
|
60
|
rt300@8
|
61 }
|
rt300@8
|
62
|
rt300@8
|
63 void setNewTestButton(Buttron * ntb){
|
rt300@8
|
64 newTestButton = ntb;
|
rt300@8
|
65 };
|
rt300@8
|
66 void set3Dbox(Leap3DBoxGL* box){
|
rt300@8
|
67 box3D = box;
|
rt300@8
|
68 };
|
rt300@9
|
69
|
rt300@9
|
70
|
rt300@8
|
71 void setCountdownPanel(CountdownText* cd){
|
rt300@8
|
72 countdownPanel = cd;
|
rt300@8
|
73 };
|
rt300@8
|
74 void setTargetSymbol(TargetSymbol* ts){
|
rt300@8
|
75 targetSymbol = ts;
|
rt300@8
|
76 };
|
rt300@8
|
77 void setScorePanel(TextPanel* tp){
|
rt300@8
|
78 scorePanel = tp;
|
rt300@8
|
79 };
|
rt300@8
|
80 void setFinishPanel(TextPanel* fp){
|
rt300@8
|
81 finishPanel = fp;
|
rt300@8
|
82 }
|
rt300@8
|
83 void setTargetButton(Buttron* tb){
|
rt300@8
|
84 targetPlayButton = tb;
|
rt300@8
|
85 }
|
rt300@8
|
86 int getScore(){
|
rt300@8
|
87 return testController->getScoreRunningTotal();
|
rt300@8
|
88 };
|
rt300@8
|
89
|
rt300@8
|
90 pair<int,int> getTime(){
|
rt300@8
|
91 TimerMillisec tms = timeController.getStopwatchElapsedTime();
|
rt300@8
|
92 int s = int(tms/1000);
|
rt300@8
|
93 int hs = int((tms%1000)/10);
|
rt300@8
|
94 pair<int,int> p(s,hs);
|
rt300@8
|
95 return p;
|
rt300@8
|
96 };
|
rt300@8
|
97 void countdownToNewTest(){
|
rt300@8
|
98
|
rt300@27
|
99 controlPanel->hide();
|
rt300@27
|
100 controlPanel->setActive(false);
|
rt300@8
|
101 scorePanel->hide();
|
rt300@8
|
102 bottomPanel->hide();
|
rt300@8
|
103 newTestButton->hide();
|
rt300@8
|
104
|
rt300@8
|
105 // set up stuff
|
rt300@8
|
106 setupNewTest();
|
rt300@8
|
107 eventLogger.logEvent(COUNTDOWN_INITIATED);
|
rt300@8
|
108
|
rt300@8
|
109 countdownPanel->showAndStart(3);
|
rt300@8
|
110
|
rt300@8
|
111 timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::startNewTest, this), 3000);
|
rt300@8
|
112
|
rt300@8
|
113 };
|
rt300@9
|
114
|
rt300@8
|
115 void playTargetButtonPressed(){
|
rt300@8
|
116
|
rt300@8
|
117 static int numPlays = 3;
|
rt300@8
|
118
|
rt300@8
|
119 Test* t = testController->getCurrentTestPtr();
|
rt300@8
|
120 if (!t->checkTargetPlaysRemaining()){
|
rt300@8
|
121 cout << t->getTargetPlaysLeft() << endl;
|
rt300@8
|
122
|
rt300@8
|
123 sendSynthValuesAgain();
|
rt300@8
|
124 targetSynth.trigger();
|
rt300@8
|
125 eventLogger.logEvent(TARGET_PLAYED);
|
rt300@8
|
126 targetPlayButton->hide();
|
rt300@8
|
127 return;
|
rt300@8
|
128
|
rt300@8
|
129 }
|
rt300@8
|
130 cout << t->getTargetPlaysLeft() << endl;
|
rt300@8
|
131
|
rt300@8
|
132 sendSynthValuesAgain();
|
rt300@8
|
133 targetSynth.trigger();
|
rt300@8
|
134 eventLogger.logEvent(TARGET_PLAYED);
|
rt300@8
|
135
|
rt300@8
|
136 return;
|
rt300@8
|
137 }
|
rt300@9
|
138
|
rt300@8
|
139 void buttonPressCallback(int mappingID, int value){
|
rt300@8
|
140 if(mappingID == VOLUME_CHANGE_ID){
|
rt300@8
|
141 targetSynth.sendVolume(value);
|
rt300@8
|
142 candidateSynth.sendVolume(value);
|
rt300@8
|
143
|
rt300@8
|
144 }
|
rt300@8
|
145 if(mappingID == SPEED_CHANGE_ID){
|
rt300@8
|
146 alternationSpeed = 2*(140 - value);
|
rt300@8
|
147 vector<int> eData;
|
rt300@8
|
148 eData.push_back(alternationSpeed);
|
rt300@8
|
149 eventLogger.logEvent(SPEED_CHANGED, eData);
|
rt300@8
|
150 }
|
rt300@8
|
151 if(mappingID == NEW_TEST_ID){
|
rt300@8
|
152 countdownToNewTest();
|
rt300@8
|
153 return;
|
rt300@8
|
154 }
|
rt300@8
|
155 if (mappingID == START_ALTERNATE_ID){
|
rt300@8
|
156 if(!playingAlternating){
|
rt300@8
|
157 startAlternatingPlayback();
|
rt300@8
|
158
|
rt300@8
|
159 }else{
|
rt300@8
|
160 stopAlternatingPlayback();
|
rt300@8
|
161 }
|
rt300@8
|
162 return;
|
rt300@8
|
163 }
|
rt300@9
|
164
|
rt300@8
|
165 if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr
|
rt300@8
|
166 targetSynth.randomiseParams();
|
rt300@8
|
167 return;
|
rt300@8
|
168 }
|
rt300@8
|
169 if (mappingID == TRIGGER_TARGET_ID){
|
rt300@8
|
170 playTargetButtonPressed();
|
rt300@8
|
171
|
rt300@8
|
172 }
|
rt300@8
|
173 if (mappingID == TRIGGER_CANDIDATE_ID){
|
rt300@8
|
174 // log event
|
rt300@8
|
175 sendSynthValuesAgain();
|
rt300@8
|
176 candidateSynth.trigger();
|
rt300@8
|
177 eventLogger.logEvent(CANDIDATE_PLAYED);
|
rt300@8
|
178 // flash panel?
|
rt300@27
|
179 controlPanel->flash();
|
rt300@8
|
180 return;
|
rt300@8
|
181 }
|
rt300@8
|
182 if (mappingID == SUBMIT_CANDIDATE){
|
rt300@8
|
183 // log event
|
rt300@8
|
184 submitPressed();
|
rt300@8
|
185
|
rt300@8
|
186 return;
|
rt300@8
|
187 }
|
rt300@8
|
188 if (mappingID == CRAP_TEST_ID){
|
rt300@8
|
189 // this is rubbish! send a log of target values, and mapping ids
|
rt300@8
|
190 vector<int> data;
|
rt300@8
|
191 vector<int> tvals = targetSynth.getAllParamValues();
|
rt300@8
|
192 vector<int> pidx = testController->getCurrentChangeableParams();
|
rt300@8
|
193 data.insert(data.end(), tvals.begin(), tvals.end());
|
rt300@8
|
194 data.insert(data.end(), pidx.begin(), pidx.end());
|
rt300@8
|
195
|
rt300@8
|
196 eventLogger.logEvent(CRAP_TEST, data);
|
rt300@8
|
197 }
|
rt300@8
|
198 if(mappingID == SHOW_HIDE_PANEL){
|
rt300@8
|
199 static bool showing;
|
rt300@8
|
200
|
rt300@8
|
201 if(showing){
|
rt300@8
|
202 cout << " showing"<<endl;
|
rt300@8
|
203
|
rt300@27
|
204 controlPanel->show();
|
rt300@8
|
205
|
rt300@8
|
206 }else{
|
rt300@8
|
207 cout << " hiding"<<endl;
|
rt300@27
|
208 controlPanel->hide();
|
rt300@8
|
209 }
|
rt300@8
|
210 showing = !showing;
|
rt300@8
|
211 }
|
rt300@8
|
212 if(mappingID == SHOW_HIDE_HINT){
|
rt300@8
|
213 static bool showingHint;
|
rt300@8
|
214 if(showingHint){
|
rt300@27
|
215 controlPanel->showHint(false);
|
rt300@8
|
216 showingHint = false;
|
rt300@8
|
217 }else{
|
rt300@27
|
218 controlPanel->showHint(true);
|
rt300@8
|
219 showingHint = true;
|
rt300@8
|
220 }
|
rt300@8
|
221 }
|
rt300@10
|
222
|
rt300@8
|
223 }
|
rt300@10
|
224
|
rt300@8
|
225 // called from UI
|
rt300@8
|
226
|
rt300@8
|
227
|
rt300@8
|
228 void midiFromLeap(int ctl_num, int ctl_val){
|
rt300@8
|
229
|
rt300@8
|
230 if (!okToGetLeapMidi){
|
rt300@8
|
231 return;
|
rt300@8
|
232 }
|
rt300@8
|
233
|
rt300@8
|
234 Test *theTest = testController->getCurrentTestPtr();
|
rt300@8
|
235 if (theTest == NULL) return;
|
rt300@8
|
236
|
rt300@8
|
237 vector<int> ci = theTest->getChangeableIndices();
|
rt300@8
|
238 vector<int> mids = candidateSynth.getMappingIDForIndices(ci);
|
rt300@8
|
239 if (ctl_num >= mids.size() || ctl_num < 0) return;
|
rt300@8
|
240
|
rt300@8
|
241 candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val);
|
rt300@8
|
242
|
rt300@8
|
243 setUIToParam(ctl_num, ctl_val);
|
rt300@8
|
244
|
rt300@8
|
245 vector<int> evtData;
|
rt300@8
|
246 evtData.push_back(mids[ctl_num]); // or just index?
|
rt300@8
|
247 evtData.push_back(ctl_val);
|
rt300@8
|
248
|
rt300@8
|
249 eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
|
rt300@9
|
250
|
rt300@8
|
251 }
|
rt300@9
|
252
|
rt300@8
|
253
|
rt300@8
|
254 ofTrueTypeFont verdBig;
|
rt300@8
|
255
|
rt300@9
|
256
|
rt300@9
|
257 protected:
|
rt300@9
|
258
|
rt300@9
|
259
|
rt300@9
|
260
|
rt300@9
|
261 // protected methods
|
rt300@9
|
262 void testsFinished(){
|
rt300@27
|
263 controlPanel->hide();
|
rt300@9
|
264 bottomPanel->hide();
|
rt300@9
|
265 newTestButton->hide();
|
rt300@9
|
266
|
rt300@9
|
267 vector<int> eData;
|
rt300@9
|
268 eData.push_back(testController->getScoreRunningTotal());
|
rt300@9
|
269 eventLogger.logEvent(ALL_TESTS_COMPLETED, eData);
|
rt300@9
|
270
|
rt300@9
|
271 // TODO set final score screen txt to testController->getScoreRunningTotal()
|
rt300@9
|
272 finishPanel->show();
|
rt300@9
|
273
|
rt300@9
|
274 string user = eventLogger.getUsername();
|
rt300@9
|
275 stringstream s;
|
rt300@9
|
276 s << "Experiment completed"
|
rt300@9
|
277 << endl << endl
|
rt300@9
|
278 << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl
|
rt300@9
|
279 << "to retake test please close " << endl << endl
|
rt300@9
|
280 << "the app and restart with username<num test>";
|
rt300@9
|
281 finishPanel->setText(s.str());
|
rt300@9
|
282 // get test app to do something...
|
rt300@9
|
283
|
rt300@9
|
284 eventLogger.saveSessionToFile();
|
rt300@9
|
285 };
|
rt300@9
|
286
|
rt300@9
|
287 void setupNewTest(){
|
rt300@9
|
288 // get mapping for new test and make sure we have right controls and stuff
|
rt300@9
|
289
|
rt300@9
|
290
|
rt300@9
|
291 Test newTest = testController->goToNextTest();
|
rt300@9
|
292
|
rt300@9
|
293 // V0.2 put details about what kind of test it is
|
rt300@9
|
294 vector<int> eData;
|
rt300@9
|
295 eData.push_back(newTest.isPractice());
|
rt300@9
|
296 eData.push_back(newTest.isWithHint());
|
rt300@9
|
297 eData.push_back(newTest.isMemoryTest());
|
rt300@9
|
298 eventLogger.logEvent(NEW_TEST, eData);
|
rt300@9
|
299
|
rt300@9
|
300
|
rt300@9
|
301 vector<int> mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest);
|
rt300@9
|
302
|
rt300@27
|
303 vector<UIElement*> UIElemHandles = controlPanel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType());
|
rt300@9
|
304
|
rt300@9
|
305 mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams);
|
rt300@9
|
306
|
rt300@9
|
307 countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning());
|
rt300@9
|
308
|
rt300@9
|
309
|
rt300@9
|
310 };
|
rt300@9
|
311 void startNewTest(){
|
rt300@9
|
312 Test t = testController->getCurrentTest();
|
rt300@9
|
313
|
rt300@9
|
314 countdownPanel->hide();
|
rt300@27
|
315 controlPanel->show();
|
rt300@27
|
316 controlPanel->setActive(true);
|
rt300@9
|
317 if(t.isWithHint()){
|
rt300@27
|
318 controlPanel->showHint(true);
|
rt300@9
|
319 }
|
rt300@9
|
320
|
rt300@9
|
321 bottomPanel->show();
|
rt300@9
|
322 targetPlayButton->show(); // incase it was memory test
|
rt300@9
|
323 if (t.isMemoryTest()){
|
rt300@9
|
324 targetPlayButton->setLabel("Memorise!");
|
rt300@9
|
325 }else{
|
rt300@9
|
326 targetPlayButton->setLabel("Target");
|
rt300@9
|
327 }
|
rt300@9
|
328
|
rt300@9
|
329 timeController.startStopwatch();
|
rt300@9
|
330 eventLogger.logEvent(TEST_TIMER_STARTED);
|
rt300@9
|
331
|
rt300@9
|
332
|
rt300@9
|
333 if(t.getListOfControlTypes()[0] == LEAP3D){
|
rt300@9
|
334 okToGetLeapMidi = true;
|
rt300@9
|
335 }
|
rt300@9
|
336 };
|
rt300@9
|
337
|
rt300@9
|
338 vector<int> setSynthsUpForNewTest(Test newTest){
|
rt300@9
|
339 targetSynth.setAllParams(newTest.getTargetValues());
|
rt300@9
|
340 eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams
|
rt300@9
|
341
|
rt300@9
|
342 candidateSynth.setAllParams(newTest.getStartingCandidateValues());
|
rt300@9
|
343 eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues());
|
rt300@9
|
344
|
rt300@9
|
345 vector<int> mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices());
|
rt300@9
|
346
|
rt300@9
|
347 eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices());
|
rt300@9
|
348 eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids);
|
rt300@9
|
349
|
rt300@9
|
350 return mids;
|
rt300@9
|
351 };
|
rt300@9
|
352
|
rt300@9
|
353
|
rt300@9
|
354 // could have been cleverer. takes forever due to searching ???
|
rt300@9
|
355 void mapUIToNewTestParams(vector<UIElement*> elems, vector<int> mids){
|
rt300@9
|
356
|
rt300@9
|
357 vector<UIElement*>::iterator elit;
|
rt300@9
|
358 vector<int> typeListLog;
|
rt300@9
|
359 int i = 0;
|
rt300@9
|
360 for(elit=elems.begin(); elit<elems.end();elit++){
|
rt300@9
|
361 if ( (*elit)->getType() == XYPAD){
|
rt300@9
|
362 if(i+1 >= mids.size()){
|
rt300@9
|
363 cout << "ERROR ERROR: too many controls for mapping IDs" << endl;
|
rt300@9
|
364 }
|
rt300@9
|
365
|
rt300@9
|
366 ButtronXY* theXY = (ButtronXY*)(*elit);
|
rt300@9
|
367 mapXYToParams(theXY, mids[i], mids[i+1]);
|
rt300@9
|
368 theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
|
rt300@9
|
369 theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))
|
rt300@9
|
370 ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1])));
|
rt300@9
|
371 i+=2;
|
rt300@9
|
372 typeListLog.push_back(int(XYPAD));
|
rt300@9
|
373 }else if ( (*elit)->getType() == SLIDER){
|
rt300@9
|
374 if(i >= mids.size()){
|
rt300@9
|
375
|
rt300@9
|
376 cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl;
|
rt300@9
|
377 }
|
rt300@9
|
378
|
rt300@9
|
379 ButtronSlider* theSlider = (ButtronSlider*)(*elit);
|
rt300@9
|
380 mapControlToParam((*elit), mids[i]);
|
rt300@9
|
381 theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i]));
|
rt300@9
|
382 cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl;
|
rt300@9
|
383 theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])));
|
rt300@9
|
384 i++;
|
rt300@9
|
385 typeListLog.push_back(int(SLIDER));
|
rt300@9
|
386 }else if ( (*elit)->getType() == LEAP3D ){
|
rt300@9
|
387 set3Dbox((Leap3DBoxGL*)(*elit));
|
rt300@9
|
388 // UH
|
rt300@9
|
389 string nameX = candidateSynth.getNameForMappingID(mids[i]);
|
rt300@9
|
390 box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX));
|
rt300@9
|
391 box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i]));
|
rt300@9
|
392 i++;
|
rt300@9
|
393
|
rt300@9
|
394 string nameY = candidateSynth.getNameForMappingID(mids[i]);
|
rt300@9
|
395 box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY));
|
rt300@9
|
396 box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i]));
|
rt300@9
|
397 i++;
|
rt300@9
|
398
|
rt300@9
|
399 string nameZ = candidateSynth.getNameForMappingID(mids[i]);
|
rt300@9
|
400 box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ));
|
rt300@9
|
401 box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i]));
|
rt300@9
|
402 i++;
|
rt300@9
|
403
|
rt300@9
|
404
|
rt300@9
|
405 box3D->setLabels(nameX,nameY,nameZ);
|
rt300@9
|
406 typeListLog.push_back(int(LEAP3D));
|
rt300@9
|
407
|
rt300@9
|
408 }else{
|
rt300@28
|
409 cout << "ERROR ERROR SEARCHMSGORG: ui type not handled my mapping function !" << endl;
|
rt300@9
|
410 }
|
rt300@9
|
411 }
|
rt300@9
|
412
|
rt300@9
|
413 eventLogger.logEvent(CONTROL_LIST,typeListLog);
|
rt300@9
|
414 };
|
rt300@9
|
415
|
rt300@9
|
416 // TODO - no, triggering playback needs to be logged
|
rt300@9
|
417 void startAlternatingPlayback(){
|
rt300@9
|
418
|
rt300@9
|
419 cout << "start alt playback" << endl;
|
rt300@9
|
420 // use our special timer to fire off play to pd
|
rt300@9
|
421 // sets off timed alternating playback
|
rt300@9
|
422
|
rt300@9
|
423 playAlternating();
|
rt300@9
|
424 playingAlternating = true;
|
rt300@9
|
425
|
rt300@9
|
426 };
|
rt300@9
|
427 void stopAlternatingPlayback(){
|
rt300@9
|
428 cout << "stop alt playback" << endl;
|
rt300@9
|
429 // kill the alternation
|
rt300@9
|
430 timeController.cancelEvent(currentSoundPlayTimer);
|
rt300@9
|
431 playingAlternating = false;
|
rt300@9
|
432 };
|
rt300@9
|
433
|
rt300@9
|
434 void playAlternating(){
|
rt300@9
|
435
|
rt300@9
|
436 static bool alt;
|
rt300@9
|
437 int nextTime;
|
rt300@9
|
438 if (alt){
|
rt300@9
|
439 targetSynth.trigger();
|
rt300@9
|
440 // flash the target thingy
|
rt300@9
|
441 targetSymbol->flash();
|
rt300@9
|
442 nextTime = alternationSpeed*1.503; // gap after target
|
rt300@9
|
443 }else{
|
rt300@9
|
444 sendSynthValuesAgain(); // and again and again
|
rt300@9
|
445 candidateSynth.trigger();
|
rt300@27
|
446 controlPanel->flash();
|
rt300@9
|
447 nextTime = alternationSpeed;
|
rt300@9
|
448 }
|
rt300@9
|
449 alt = !alt;
|
rt300@9
|
450 candidateSynth.setNoteLength(alternationSpeed);
|
rt300@9
|
451 targetSynth.setNoteLength(alternationSpeed); // could be user alterable
|
rt300@9
|
452 currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::playAlternating,this), nextTime);
|
rt300@9
|
453
|
rt300@9
|
454
|
rt300@9
|
455
|
rt300@9
|
456 };
|
rt300@9
|
457
|
rt300@9
|
458 void delayedShowNewTest(){
|
rt300@9
|
459 newTestButton->show();
|
rt300@9
|
460 // JUST IN CASE IT CRASHES near end...
|
rt300@9
|
461 //eventLogger.saveSessionToFile();
|
rt300@9
|
462 };
|
rt300@9
|
463 void submitSingleControl(){
|
rt300@9
|
464 // if last one
|
rt300@9
|
465 // submitPressed()
|
rt300@9
|
466
|
rt300@9
|
467 // else
|
rt300@9
|
468
|
rt300@9
|
469 // grey out that slider,
|
rt300@9
|
470 // activate next slider and show it's button (same button but moved!???)
|
rt300@9
|
471
|
rt300@9
|
472 };
|
rt300@9
|
473
|
rt300@9
|
474
|
rt300@9
|
475 void submitPressed(){
|
rt300@9
|
476
|
rt300@9
|
477 // depending on mode go to next control
|
rt300@9
|
478 // if(testController->getCurrentPanelType() == SEQUENTIAL){
|
rt300@9
|
479 // submitSingleControl();
|
rt300@9
|
480 // return;
|
rt300@9
|
481 // }
|
rt300@9
|
482 // otherwise do this other - or call
|
rt300@9
|
483
|
rt300@9
|
484 okToGetLeapMidi = false;
|
rt300@9
|
485
|
rt300@9
|
486 TimerMillisec timeTaken = timeController.stopStopwatch();
|
rt300@9
|
487 vector<int> answer = candidateSynth.getAllParamValues();
|
rt300@9
|
488
|
rt300@9
|
489 eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?));
|
rt300@9
|
490
|
rt300@9
|
491 TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results
|
rt300@9
|
492
|
rt300@9
|
493 vector<int> logResult;
|
rt300@9
|
494 logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??!
|
rt300@9
|
495 logResult.push_back(result.timeTaken); // milliseconds
|
rt300@9
|
496 logResult.push_back(result.score);
|
rt300@9
|
497 logResult.push_back(result.targetBandHit);
|
rt300@9
|
498 logResult.push_back(result.timeWindowHit);
|
rt300@9
|
499
|
rt300@9
|
500 eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult);
|
rt300@9
|
501
|
rt300@9
|
502
|
rt300@9
|
503 // gui stuff - different controller?
|
rt300@27
|
504 controlPanel->setActive(false);
|
rt300@27
|
505 controlPanel->showHint(true); // add some encouraging feedback to hint
|
rt300@9
|
506 bottomPanel->hide();
|
rt300@9
|
507
|
rt300@9
|
508 showScoreForTest(result);
|
rt300@9
|
509
|
rt300@9
|
510 stopAlternatingPlayback();
|
rt300@9
|
511
|
rt300@9
|
512 // was it the final sumbit?
|
rt300@9
|
513 if(testController->isLastTest()){
|
rt300@9
|
514 // thats it - show a final score screen etc
|
rt300@9
|
515 timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::testsFinished, this), 500);
|
rt300@9
|
516 return;
|
rt300@9
|
517 }else{
|
rt300@9
|
518 timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::delayedShowNewTest, this), 300);
|
rt300@9
|
519 }
|
rt300@9
|
520
|
rt300@9
|
521
|
rt300@9
|
522 };
|
rt300@9
|
523
|
rt300@9
|
524 void showScoreForTest(TestResult result){
|
rt300@9
|
525 scorePanel->setText(result.displayText);
|
rt300@9
|
526 scorePanel->show();
|
rt300@9
|
527
|
rt300@9
|
528 ofColor c;
|
rt300@9
|
529 if(result.targetBandHit == 1){
|
rt300@9
|
530 // yellow red blue
|
rt300@9
|
531 c = ofColor(255,255,0,255);
|
rt300@9
|
532 }else if(result.targetBandHit == 2){
|
rt300@9
|
533 c = ofColor(255,0,0,255);
|
rt300@9
|
534 }else if(result.targetBandHit == 3){
|
rt300@9
|
535 c = ofColor(45,45,255,255);
|
rt300@9
|
536 }else if(result.targetBandHit == 4){
|
rt300@9
|
537 c = ofColor(0,255,0,255);
|
rt300@9
|
538 }else{
|
rt300@9
|
539 c = ofColor(150,235,200,255);
|
rt300@9
|
540 }
|
rt300@9
|
541 scorePanel->setColor(c);
|
rt300@27
|
542 controlPanel->setHintColor(c);
|
rt300@9
|
543 };
|
rt300@9
|
544
|
rt300@24
|
545
|
rt300@24
|
546
|
rt300@24
|
547 TimeController altPlaybackController;
|
rt300@24
|
548
|
rt300@24
|
549 TestController* testController;
|
rt300@24
|
550 Buttron* newTestButton;
|
rt300@24
|
551 //Buttron* submitButton;
|
rt300@24
|
552
|
rt300@24
|
553
|
rt300@24
|
554 Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand
|
rt300@24
|
555 CountdownText* countdownPanel;
|
rt300@24
|
556 TargetSymbol* targetSymbol;
|
rt300@24
|
557 Leap3DBoxGL* box3D;
|
rt300@24
|
558 TextPanel* scorePanel;
|
rt300@24
|
559 TextPanel* finishPanel;
|
rt300@24
|
560
|
rt300@24
|
561 //int scoreRunningTotal;
|
rt300@24
|
562 TimerID currentSoundPlayTimer;
|
rt300@24
|
563
|
rt300@24
|
564 int alternationSpeed; // ms between cand and target
|
rt300@24
|
565 bool playingAlternating;
|
rt300@24
|
566
|
rt300@24
|
567 bool okToGetLeapMidi;
|
rt300@9
|
568
|
rt300@8
|
569 };
|
rt300@8
|
570
|
rt300@8
|
571 #endif /* defined(__riftathon__SearchMessageOrganiser__) */
|