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