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__) */