annotate eventLogger.h @ 52:89944ab3e129 tip

fix oF linker errors ios8
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Tue, 03 Feb 2015 13:18:23 +0000
parents 80112c9349c4
children
rev   line source
rt300@0 1 //
rt300@0 2 // eventLogger.h
rt300@0 3 // oscSenderExample
rt300@0 4 //
rt300@0 5 // Created by Robert Tubb on 05/11/2012.
rt300@0 6 //
rt300@0 7 //
rt300@0 8 // This class handle everything to do with loggin user actions,
rt300@0 9 // uploading logs to server, and storing locally if not uploaded
rt300@0 10
rt300@0 11 #ifndef __oscSenderExample__eventLogger__
rt300@0 12 #define __oscSenderExample__eventLogger__
rt300@0 13
rt300@0 14
rt300@0 15 #include "ofMain.h"
rt300@0 16 #include "ofxiPhone.h"
rt300@0 17 #include "2dvector.h"
rt300@0 18 #include "ofxiPhoneExtras.h"
rt300@0 19 #include <sys/time.h>
rt300@0 20 #include <iostream>
rt300@0 21 #include <string>
rt300@0 22 #include <cstring>
rt300@0 23 #include <map>
rt300@0 24 #include "2dvector.h"
rt300@0 25 #include "json.h"
rt300@0 26 #import "ServerComms.h"
rt300@0 27 #include "boost/bind.hpp"
rt300@0 28 #include "boost/function.hpp"
rt300@0 29 #include "Poco/Mutex.h"
rt300@32 30
rt300@0 31 #define EVENT_THIN_FACTOR 30
rt300@0 32 #define EVENT_LOG_FILENAME "log.json"
rt300@0 33 #define UPLOAD_CHUNK_SIZE 1000
rt300@34 34 #define SAVE_CHUNK_SIZE 30000 // this is "too big" and must be saved, usually run end will save
rt300@0 35 #define APP_CREATION_TIME 0 // ignore this, pointless
rt300@18 36 #define PROGRAM_NAME "RIFTATHON"
rt300@18 37 #define PROGRAM_VERSION 0.1
rt300@0 38
rt300@0 39 #define SUPERVISED // this def will save files
rt300@0 40
rt300@0 41
rt300@0 42 // can add but don't change ordering - this will invalidate logs
rt300@0 43 enum leventType {APP_LOADED, // 0
rt300@0 44 INTRO_CONSENTED, // 1
rt300@0 45 APP_EXITED, // 2
rt300@0 46 HELP_PRESSED, // 3
rt300@0 47 QUESTIONNAIRE_COMPLETED, // 4
rt300@0 48
rt300@0 49 NEW_TEST, // 5
rt300@0 50 // al the set up of the new test
rt300@0 51 TARGET_PARAM_SET, // 6 setting up the target sound, param id and value
rt300@0 52 CANDIDATE_PARAM_SET, // 7 setting up the cand sound starting pos, subset of param id and value
rt300@0 53 CANDIDATE_CHANGEABLE_IDX, // 8 list of changeable indexes
rt300@0 54 CANDIDATE_MAPPING_IDS, // 9 which kind of control was mapped to which param
rt300@0 55 CONTROL_LIST, // 10 list of control types
rt300@0 56
rt300@0 57 TEST_TIMER_STARTED, // 11 we're off!!
rt300@0 58
rt300@0 59 CANDIDATE_PARAM_ADJUSTED, // 12 interactions changing params
rt300@0 60 SUBMIT_PRESSED, // 13 this is the suer saying they've found it, along with the actual answer
rt300@0 61 DISTANCE_TIME_SCORE, // 14 list of the results, now we should go back to NEW_TEST
rt300@0 62 COUNTDOWN_INITIATED, // 15 just in case
rt300@0 63 ALL_TESTS_COMPLETED, // 16 ?
rt300@0 64 TARGET_PLAYED, // 17 however this happens it might be good to know when this happens
rt300@0 65 CANDIDATE_PLAYED, // 18
rt300@9 66 START_THE_SEARCH_TESTS, // 19 probably superfluous
rt300@0 67 CRAP_TEST, // eliminate these coords somehow ???
rt300@0 68 EMPTY_EVENT,
rt300@0 69 SPEED_CHANGED, // 22 ms between sounds
rt300@9 70 SAVE_PRESET, // 23 save a preset
rt300@16 71 START_THE_TRAINING_TESTS, // 24 start traning
rt300@32 72 START_THE_EXP_TESTS, // 25 start explore/express
rt300@32 73 START_THE_PERFORMANCE_TESTS, // 26 starting perf
rt300@32 74
rt300@32 75 // new stuff for TRaining stage
rt300@43 76 START_NEW_RUN, // 27
rt300@43 77 TRAINING_RESULT, // 28
rt300@43 78 NEW_STEP, // 29
rt300@43 79 NEW_TARGET, // 30
rt300@43 80 NEW_START_POS, //31
rt300@43 81 FINISH_POS, //32
rt300@43 82 FINISHED_RUN, //33
rt300@43 83 CANDIDATE_PARAM_ADJUSTED_ALL, //34
rt300@43 84 TARGET_AND_MATCH, //35
rt300@43 85 FORGOT_SEQ, //36
rt300@45 86 RUN_SKIPPED, //37
rt300@45 87 START_THE_TRAINING_DEMO
rt300@0 88
rt300@0 89 };
rt300@0 90
rt300@0 91 //---------------------------------------------------------------------------
rt300@0 92
rt300@0 93 class lEvent{
rt300@0 94 public:
rt300@0 95 // try and make this as compact as possible.
rt300@0 96 leventType eventType;
rt300@0 97 double val1; // x coord, scale if zoom
rt300@0 98 double val2; // y coord, 0 if zoom
rt300@0 99 int sliderID; // xtra int
rt300@0 100 long long eventTime; // MILLISECONDS since ref date
rt300@0 101 vector<int> eventData; // variable length data int
rt300@0 102
rt300@0 103 // old sonic zoom style event
rt300@0 104 lEvent(leventType eType, double v1 = 0.0, double v2 = 0.0,int sID = 0){
rt300@0 105 eventType = eType;
rt300@0 106 val1 = v1;
rt300@0 107 val2 = v2;
rt300@0 108 sliderID = sID;
rt300@0 109
rt300@0 110 double timemsd = [NSDate timeIntervalSinceReferenceDate]; // MILLISECONDS, but with fractional part (
rt300@0 111 eventTime = (unsigned long long)(timemsd*1000) - APP_CREATION_TIME;
rt300@0 112
rt300@0 113 }
rt300@0 114
rt300@0 115 // new tweakathlon event
rt300@0 116 lEvent(leventType eType, vector<int> theData){
rt300@0 117 eventType = eType;
rt300@0 118 eventData = theData;
rt300@0 119
rt300@0 120 double timemsd = [NSDate timeIntervalSinceReferenceDate]; // MILLISECONDS, but with fractional part (
rt300@0 121 eventTime = (unsigned long long)(timemsd*1000) - APP_CREATION_TIME;
rt300@0 122
rt300@0 123 }
rt300@0 124
rt300@0 125 lEvent(const Json::Value &jevt){
rt300@0 126 // constructor takes "jsonToEvent" readfile function role
rt300@0 127 eventType = (leventType)jevt["eType"].asInt();
rt300@0 128 val1 = jevt["v1"].asDouble();
rt300@0 129 val2 = jevt["v2"].asDouble();
rt300@0 130 sliderID = jevt["sID"].asInt();
rt300@0 131 eventTime = jevt["eTime"].asLargestInt();
rt300@0 132
rt300@0 133 // TODO what happens if we try to read one that isn't there?
rt300@0 134
rt300@0 135 }
rt300@0 136 // new tweak event to json
rt300@0 137 Json::Value eventToJson(){
rt300@0 138 Json::Value jevt;
rt300@0 139 jevt["eType"] = eventType;
rt300@0 140 // convert vector to json array
rt300@0 141 for(auto it = eventData.begin(); it < eventData.end(); it++){
rt300@0 142 jevt["eData"].append(*it);
rt300@0 143 }
rt300@0 144 jevt["eTime"] = eventTime;
rt300@0 145 return jevt;
rt300@0 146 }
rt300@0 147 Json::Value eventToJsonOld(){
rt300@0 148 Json::Value jevt;
rt300@0 149 jevt["eType"] = eventType;
rt300@0 150 // here: should give a certain number of sig figs?
rt300@0 151 jevt["v1"] = val1;
rt300@0 152 jevt["v2"] = val2;
rt300@0 153 jevt["sID"] = sliderID;
rt300@0 154 jevt["eTime"] = eventTime;
rt300@0 155 return jevt;
rt300@0 156 }
rt300@0 157 };
rt300@0 158
rt300@0 159
rt300@0 160 //------------------------------------------
rt300@0 161
rt300@0 162 class EventLogger{
rt300@0 163 public:
rt300@0 164 Poco::Mutex _mutex;
rt300@0 165
rt300@0 166 int nextUploadNumber;
rt300@0 167 int nextUploadQty;
rt300@0 168 bool loggingEnabled;
rt300@0 169
rt300@0 170 bool logUploadInProgress;
rt300@0 171 bool serverConnectionOK;
rt300@0 172 bool consentGiven;
rt300@0 173 bool questionnaireCompleted;
rt300@0 174 bool questionnaireUploaded;
rt300@0 175
rt300@34 176 unsigned long long deviceID;
rt300@34 177 unsigned long long totalInteractionTime, savedInteractionTime, sessionTime, sessionStartTime;
rt300@0 178 string userName; // not unique
rt300@0 179 string questionnaireComments;
rt300@0 180 // constr
rt300@0 181 EventLogger();
rt300@0 182
rt300@0 183 // public methods:
rt300@18 184 void onUsernameEntered();
rt300@0 185 void startLoadAll();
rt300@0 186 void exitAndSave();
rt300@0 187 void setUsername(const char *u);
rt300@0 188 string getUsername(){
rt300@0 189 return userName;
rt300@0 190 }
rt300@0 191 void newUser();
rt300@0 192 void logEvent(const leventType& evtType);
rt300@0 193 void logEvent(const leventType& evtType, const vector<int> eventData);
rt300@0 194
rt300@0 195 void questionnaireAnswersObtained(vector<int> answers, const char* userComments);
rt300@0 196 void urlResponse(ofHttpResponse & response);
rt300@0 197
rt300@0 198 void questionnaireOK();
rt300@0 199 void eventlogOK();
rt300@0 200 void testConnectionOK();
rt300@0 201 void questionnaireNotOK();
rt300@0 202 void eventlogNotOK();
rt300@0 203 void testConnectionNotOK();
rt300@0 204
rt300@0 205 void printAll();
rt300@0 206 void saveSessionToFile();
rt300@0 207
rt300@0 208 private:
rt300@0 209 void thinnedSliderEvent(lEvent newEvent);
rt300@0 210 vector<lEvent> theEvents; // all logged but not uploaded events
rt300@0 211
rt300@0 212 vector<int> questionnaireAnswers;
rt300@0 213
rt300@18 214 string nextLogFileIndexString();
rt300@18 215 void loadUserDetailsFromLastLogFile(int numExistingLogs);
rt300@0 216 // private methods
rt300@0 217 void testConnection();
rt300@0 218 void checkLogFile();
rt300@0 219 void deleteLogs(); // new user
rt300@0 220 bool uploadEventLog(bool async);
rt300@0 221 void firstEverAppOpen();
rt300@0 222 void loadExistingLogFile(const string &jsonFile);
rt300@0 223 void uploadQuestionnaire();
rt300@0 224 bool sendToServer(string functionName, Json::Value jsonData, bool async);
rt300@0 225
rt300@0 226 Json::Value logsToJson();
rt300@0 227 Json::Value questionnaireToJson();
rt300@0 228
rt300@0 229
rt300@0 230 template<class T> bool matchID(T thing);
rt300@0 231 bool matchID2();
rt300@0 232 //
rt300@0 233 ServerComms *serverComms;
rt300@18 234 int nextLogFileIndex;
rt300@0 235 };
rt300@0 236
rt300@0 237
rt300@0 238 //---------------------------------------------------------------------------
rt300@0 239
rt300@0 240
rt300@0 241 #endif /* defined(__oscSenderExample__eventLogger__) */