Mercurial > hg > tweakathon2ios
diff MessageOrganiser.h @ 8:d59de9fd3496
Refactored messageController, ready for instroduction of other stages and tests.
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Fri, 17 Oct 2014 16:35:22 +0100 |
parents | 92850a2b099c |
children | d5e928887f51 |
line wrap: on
line diff
--- a/MessageOrganiser.h Fri Oct 17 15:13:35 2014 +0100 +++ b/MessageOrganiser.h Fri Oct 17 16:35:22 2014 +0100 @@ -19,8 +19,6 @@ #include <Buttron.h> #include <ButtronSlider.h> #include <ButtronXY.h> -#include "AppCore.h" -#include "ofxPd.h" #include "TestController.h" #include "timeController.h" #include "PDSynthWrapper.h" @@ -60,327 +58,35 @@ typedef boost::function<void(void)> AppModeChangeFunction; class MessageOrganiser { -private: - AppCore* core; - //testApp* theOFApp; + +public: + void init(PDSynthWrapper& cs, PDSynthWrapper& ts){ + candidateSynth = cs; + targetSynth = ts; + } + // could template for ui element type?? + void mapButtonToAction(UIElement* control, int mappingID){ + UICallbackFunction callbackF; + callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2); + control->addHandler(callbackF, mappingID); + currentMapping.insert(std::pair<int,UIElement*>(mappingID,control)); + } +protected: + + PDSynthWrapper candidateSynth; PDSynthWrapper targetSynth; - PDSynthWrapper candidateSynth; + map<int,UIElement*> currentMapping; // could get more sophisticated if not 1-1 ? SliderPanel* panel; - TimeController altPlaybackController; - TestController* testController; - Buttron* newTestButton; - //Buttron* submitButton; - - ButtonPanel* bottomPanel; // shows during test : play buttons and submit - Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand - CountdownText* countdownPanel; - TargetSymbol* targetSymbol; - Leap3DBoxGL* box3D; - TextPanel* scorePanel; - TextPanel* finishPanel; - AppModeChangeFunction testAppModeChange; - - //int scoreRunningTotal; - TimerID currentSoundPlayTimer; - - int alternationSpeed; // ms between cand and target - bool playingAlternating; - - bool okToGetLeapMidi; - void testsFinished(){ - panel->hide(); - bottomPanel->hide(); - newTestButton->hide(); - - vector<int> eData; - eData.push_back(testController->getScoreRunningTotal()); - eventLogger.logEvent(ALL_TESTS_COMPLETED, eData); - - // TODO set final score screen txt to testController->getScoreRunningTotal() - finishPanel->show(); - - string user = eventLogger.getUsername(); - stringstream s; - s << "Experiment completed" - << endl << endl - << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl - << "to retake test please close " << endl << endl - << "the app and restart with username<num test>"; - finishPanel->setText(s.str()); - // get test app to do something... - - eventLogger.saveSessionToFile(); - }; - - void setupNewTest(){ - // get mapping for new test and make sure we have right controls and stuff - - - Test newTest = testController->goToNextTest(); - - // V0.2 put details about what kind of test it is - vector<int> eData; - eData.push_back(newTest.isPractice()); - eData.push_back(newTest.isWithHint()); - eData.push_back(newTest.isMemoryTest()); - eventLogger.logEvent(NEW_TEST, eData); - - - vector<int> mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest); - - vector<UIElement*> UIElemHandles = panel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType()); - - mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams); - - countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning()); - - - }; - void startNewTest(){ - Test t = testController->getCurrentTest(); - - countdownPanel->hide(); - panel->show(); - panel->setActive(true); - if(t.isWithHint()){ - panel->showHint(true); - } - - bottomPanel->show(); - targetPlayButton->show(); // incase it was memory test - if (t.isMemoryTest()){ - targetPlayButton->setLabel("Memorise!"); - }else{ - targetPlayButton->setLabel("Target"); - } - //startAlternatingPlayback(); - //timeController.scheduleEvent(boost::bind(&MessageOrganiser::sendSynthValuesAgain, this), 200); - timeController.startStopwatch(); - eventLogger.logEvent(TEST_TIMER_STARTED); - - - if(t.getListOfControlTypes()[0] == LEAP3D){ - okToGetLeapMidi = true; - } - }; - - vector<int> setSynthsUpForNewTest(Test newTest){ - targetSynth.setAllParams(newTest.getTargetValues()); - eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams - - candidateSynth.setAllParams(newTest.getStartingCandidateValues()); - eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues()); - - // eventLogger.logEvent(NEW_TARGET_PARAMS, vector<int> ); - // eventLogger.logEvent(NEW_CANDIDATE_PARAMS, vector<int> ); - - vector<int> mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices()); - - eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices()); - eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids); - - return mids; - }; void sendSynthValuesAgain(){ candidateSynth.sendAllParams(); targetSynth.sendAllParams(); }; - - // could have been cleverer. takes forever due to searching ??? - void mapUIToNewTestParams(vector<UIElement*> elems, vector<int> mids){ - - vector<UIElement*>::iterator elit; - vector<int> typeListLog; - int i = 0; - for(elit=elems.begin(); elit<elems.end();elit++){ - if ( (*elit)->getType() == XYPAD){ - if(i+1 >= mids.size()){ - cout << "ERROR ERROR: too many controls for mapping IDs" << endl; - } - - ButtronXY* theXY = (ButtronXY*)(*elit); - mapXYToParams(theXY, mids[i], mids[i+1]); - theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1])); - theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) - ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1]))); - i+=2; - typeListLog.push_back(int(XYPAD)); - }else if ( (*elit)->getType() == SLIDER){ - if(i >= mids.size()){ - - cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl; - } - - ButtronSlider* theSlider = (ButtronSlider*)(*elit); - mapControlToParam((*elit), mids[i]); - theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i])); - cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl; - theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))); - i++; - typeListLog.push_back(int(SLIDER)); - }else if ( (*elit)->getType() == LEAP3D ){ - set3Dbox((Leap3DBoxGL*)(*elit)); - // UH - string nameX = candidateSynth.getNameForMappingID(mids[i]); - box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX)); - box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i])); - i++; - - string nameY = candidateSynth.getNameForMappingID(mids[i]); - box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY)); - box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i])); - i++; - - string nameZ = candidateSynth.getNameForMappingID(mids[i]); - box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ)); - box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i])); - i++; - - - box3D->setLabels(nameX,nameY,nameZ); - typeListLog.push_back(int(LEAP3D)); - - }else{ - cout << "ERROR ERROR: ui type not handled my mapping function !" << endl; - } - } - - eventLogger.logEvent(CONTROL_LIST,typeListLog); - }; - - // TODO - no, triggering playback needs to be logged - void startAlternatingPlayback(){ - - cout << "start alt playback" << endl; - // use our special timer to fire off play to pd - // sets off timed alternating playback - - playAlternating(); - playingAlternating = true; - - }; - void stopAlternatingPlayback(){ - cout << "stop alt playback" << endl; - // kill the alternation - timeController.cancelEvent(currentSoundPlayTimer); - playingAlternating = false; - }; - - void playAlternating(){ - - static bool alt; - int nextTime; - if (alt){ - targetSynth.trigger(); - // flash the target thingy - targetSymbol->flash(); - nextTime = alternationSpeed*1.503; // gap after target - }else{ - sendSynthValuesAgain(); // and again and again - candidateSynth.trigger(); - panel->flash(); - nextTime = alternationSpeed; - } - alt = !alt; - candidateSynth.setNoteLength(alternationSpeed); - targetSynth.setNoteLength(alternationSpeed); // could be user alterable - currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&MessageOrganiser::playAlternating,this), nextTime); - - - - }; - - void delayedShowNewTest(){ - newTestButton->show(); - // JUST IN CASE IT CRASHES near end... - //eventLogger.saveSessionToFile(); - }; - void submitSingleControl(){ - // if last one - // submitPressed() - - // else - - // grey out that slider, - // activate next slider and show it's button (same button but moved!???) - - }; - - - void submitPressed(){ - - // depending on mode go to next control - // if(testController->getCurrentPanelType() == SEQUENTIAL){ - // submitSingleControl(); - // return; - // } - // otherwise do this other - or call - - okToGetLeapMidi = false; - - TimerMillisec timeTaken = timeController.stopStopwatch(); - vector<int> answer = candidateSynth.getAllParamValues(); - - eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?)); - - TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results - - vector<int> logResult; - logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??! - logResult.push_back(result.timeTaken); // milliseconds - logResult.push_back(result.score); - logResult.push_back(result.targetBandHit); - logResult.push_back(result.timeWindowHit); - - eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult); - - - // gui stuff - different controller? - panel->setActive(false); - panel->showHint(true); // add some encouraging feedback to hint - bottomPanel->hide(); - - showScoreForTest(result); - - stopAlternatingPlayback(); - - // was it the final sumbit? - if(testController->isLastTest()){ - // thats it - show a final score screen etc - timeController.scheduleEvent(boost::bind(&MessageOrganiser::testsFinished, this), 500); - return; - }else{ - timeController.scheduleEvent(boost::bind(&MessageOrganiser::delayedShowNewTest, this), 300); - } - - - }; - - void showScoreForTest(TestResult result){ - scorePanel->setText(result.displayText); - scorePanel->show(); - - ofColor c; - if(result.targetBandHit == 1){ - // yellow red blue - c = ofColor(255,255,0,255); - }else if(result.targetBandHit == 2){ - c = ofColor(255,0,0,255); - }else if(result.targetBandHit == 3){ - c = ofColor(45,45,255,255); - }else if(result.targetBandHit == 4){ - c = ofColor(0,255,0,255); - }else{ - c = ofColor(150,235,200,255); - } - scorePanel->setColor(c); - panel->setHintColor(c); - }; + void setAllSlidersToValues(vector<int> values){ for(int i = 0; i < values.size(); i++){ @@ -435,28 +141,7 @@ control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY)); }; - - void mapLeapToParams(ButtronXY* control, int mappingIDX, int mappingIDY, int mappingIDZ){ -// UICallbackFunction callbackX; -// UICallbackFunction callbackY; -// UICallbackFunction callbackZ; -// -// callbackX = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); -// callbackY = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); -// callbackZ = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); -// -// control->addHandler(callbackX, mappingIDX); -// control->addHandler(callbackY, mappingIDY); -// -// // put in our map so we can send param values to gui -// //currentMapping.insert(std::pair<int,UIElement*>(mappingID,control)); -// -// -// cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl; -// cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl; -// control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY)); - - }; + void mapControlToParam(UIElement* control, string paramName){ // get mapping ID from synth @@ -464,276 +149,13 @@ mapControlToParam(control, mappingID); control->setLabel(paramName); }; -public: - void init(AppCore* aCore, TestController* tc){ - // set PD core... - core = aCore; - targetSynth.init(aCore,"targetSynth"); - candidateSynth.init(aCore,"candidateSynth"); - - testController = tc; - currentSoundPlayTimer = -1; - okToGetLeapMidi = false; - - alternationSpeed = 200; - - candidateSynth.setNoteLength(alternationSpeed); - targetSynth.setNoteLength(alternationSpeed); - - playingAlternating = false; + virtual void paramChangeCallback(int mappingID, int value){ + // virtual? }; - void setNewTestButton(Buttron * ntb){ - newTestButton = ntb; - }; - void set3Dbox(Leap3DBoxGL* box){ - box3D = box; - }; - void setBottomPanel(ButtonPanel * ntb){ - bottomPanel = ntb; - }; - void setControlPanel(SliderPanel* p){ - panel = p; + virtual void buttonPressCallback(int mappingID, int value){ }; - void setCountdownPanel(CountdownText* cd){ - countdownPanel = cd; - }; - void setTargetSymbol(TargetSymbol* ts){ - targetSymbol = ts; - }; - void setScorePanel(TextPanel* tp){ - scorePanel = tp; - }; - void setFinishPanel(TextPanel* fp){ - finishPanel = fp; - } - void setTargetButton(Buttron* tb){ - targetPlayButton = tb; - } - int getScore(){ - return testController->getScoreRunningTotal(); - }; - - pair<int,int> getTime(){ - TimerMillisec tms = timeController.getStopwatchElapsedTime(); - int s = int(tms/1000); - int hs = int((tms%1000)/10); - pair<int,int> p(s,hs); - return p; - }; - void countdownToNewTest(){ - - panel->hide(); - panel->setActive(false); - scorePanel->hide(); - bottomPanel->hide(); - newTestButton->hide(); - - // set up stuff - setupNewTest(); - eventLogger.logEvent(COUNTDOWN_INITIATED); - - countdownPanel->showAndStart(3); - - timeController.scheduleEvent(boost::bind(&MessageOrganiser::startNewTest, this), 3000); - - }; - void sendToGUI(vector<int> paramsToMap){ - // look up these ids in mapping table - }; - void saveGoodTest(Test t){ - - }; - void playTargetButtonPressed(){ - - static int numPlays = 3; - - Test* t = testController->getCurrentTestPtr(); - if (!t->checkTargetPlaysRemaining()){ - cout << t->getTargetPlaysLeft() << endl; - - sendSynthValuesAgain(); - targetSynth.trigger(); - eventLogger.logEvent(TARGET_PLAYED); - targetPlayButton->hide(); - return; - - } - cout << t->getTargetPlaysLeft() << endl; - - sendSynthValuesAgain(); - targetSynth.trigger(); - eventLogger.logEvent(TARGET_PLAYED); - - return; - } - void playCandidateButtonPressed(){ - // - } - void buttonPressCallback(int mappingID, int value){ - if(mappingID == VOLUME_CHANGE_ID){ - targetSynth.sendVolume(value); - candidateSynth.sendVolume(value); - - } - if(mappingID == SPEED_CHANGE_ID){ - alternationSpeed = 2*(140 - value); - vector<int> eData; - eData.push_back(alternationSpeed); - eventLogger.logEvent(SPEED_CHANGED, eData); - } - if(mappingID == NEW_TEST_ID){ - countdownToNewTest(); - return; - } - if (mappingID == START_ALTERNATE_ID){ - if(!playingAlternating){ - startAlternatingPlayback(); - - }else{ - stopAlternatingPlayback(); - } - return; - } - if(mappingID == GOOD_TEST_ID){ - Test t = testController->getCurrentTest(); - saveGoodTest(t); - } - if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr - targetSynth.randomiseParams(); - return; - } - if (mappingID == TRIGGER_TARGET_ID){ - playTargetButtonPressed(); - - } - if (mappingID == TRIGGER_CANDIDATE_ID){ - // log event - sendSynthValuesAgain(); - candidateSynth.trigger(); - eventLogger.logEvent(CANDIDATE_PLAYED); - // flash panel? - panel->flash(); - return; - } - if (mappingID == SUBMIT_CANDIDATE){ - // log event - submitPressed(); - - return; - } - if (mappingID == CRAP_TEST_ID){ - // this is rubbish! send a log of target values, and mapping ids - vector<int> data; - vector<int> tvals = targetSynth.getAllParamValues(); - vector<int> pidx = testController->getCurrentChangeableParams(); - data.insert(data.end(), tvals.begin(), tvals.end()); - data.insert(data.end(), pidx.begin(), pidx.end()); - - eventLogger.logEvent(CRAP_TEST, data); - } - if(mappingID == SHOW_HIDE_PANEL){ - static bool showing; - - if(showing){ - cout << " showing"<<endl; - - panel->show(); - - }else{ - cout << " hiding"<<endl; - panel->hide(); - } - showing = !showing; - } - if(mappingID == SHOW_HIDE_HINT){ - static bool showingHint; - if(showingHint){ - panel->showHint(false); - showingHint = false; - }else{ - panel->showHint(true); - showingHint = true; - } - } - if(mappingID == SAVE_PRESET_HIT){ - expPresetManager.savePreset("blah", candidateSynth.getAllParamValues()); - - } - if(mappingID == RECALL_PRESET_HIT){ - - loadPreset("blah"); - //candidateSynth.startMetronome(); - - } - } - void loadPreset(string pname){ - - vector<int> values = expPresetManager.recallPreset(pname); - if (values.size()){ - candidateSynth.setAllParams(values); - setAllSlidersToValues(values); - }else{ - cout << "ERROR, no preset found" << endl; - } - } - // called from UI - void paramChangeCallback(int mappingID, int value){ - candidateSynth.paramChangeCallback(mappingID, value); - vector<int> evtData; - evtData.push_back(mappingID); // or just index? - evtData.push_back(value); - - eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData); - }; - - // could template for ui element type?? - void mapButtonToAction(UIElement* control, int mappingID){ - UICallbackFunction callbackF; - callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2); - control->addHandler(callbackF, mappingID); - currentMapping.insert(std::pair<int,UIElement*>(mappingID,control)); - } - - - void midiFromLeap(int ctl_num, int ctl_val){ - - - if (!okToGetLeapMidi){ - return; - } - - - Test *theTest = testController->getCurrentTestPtr(); - if (theTest == NULL) return; - - - - - - vector<int> ci = theTest->getChangeableIndices(); - vector<int> mids = candidateSynth.getMappingIDForIndices(ci); - if (ctl_num >= mids.size() || ctl_num < 0) return; - - candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val); - - setUIToParam(ctl_num, ctl_val); - - vector<int> evtData; - evtData.push_back(mids[ctl_num]); // or just index? - evtData.push_back(ctl_val); - - eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData); - // also call UI object - // get mapping ID for - // setUIToParam(ctl_num, ctl_val); - } -// void setSlidersFromLeap(int i, int val){ -// ButtronSlider* theSlider = (ButtronSlider*)panel->getSlider(i); -// theSlider->setValueAndScale(val); -// } - void setSlidersToTarget(){