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@1
|
14
|
rt300@4
|
15 #include "ofMain.h"
|
rt300@4
|
16 #include "ofxiPhone.h"
|
rt300@4
|
17 #include "2dvector.h"
|
rt300@4
|
18 #include "ofxiPhoneExtras.h"
|
rt300@4
|
19 #include <sys/time.h>
|
rt300@4
|
20 #include <iostream>
|
rt300@4
|
21 #include <string>
|
rt300@22
|
22 #include <cstring>
|
rt300@4
|
23 #include <map>
|
rt300@4
|
24 #include "2dvector.h"
|
rt300@8
|
25 #include "json.h"
|
rt300@24
|
26 #include "testApp.h"
|
rt300@8
|
27
|
rt300@16
|
28
|
rt300@8
|
29
|
rt300@25
|
30
|
rt300@25
|
31
|
rt300@25
|
32 #define EVENT_LOG_FILENAME "log.json"
|
rt300@25
|
33 #define SERVER_URL "http://127.0.0.1:8080/testservice/"
|
rt300@25
|
34 #define UPLOAD_CHUNK_SIZE 500
|
rt300@25
|
35 #define QUESTIONNAIRE_ENABLE_TIME 100000 // milliseconds
|
rt300@25
|
36 #define APP_CREATION_TIME 381429000000 // milliseconds to the time i wrote this wee blighter
|
rt300@25
|
37
|
rt300@25
|
38 #define PROGRAM_VERSION 1.0 // IMPORTANT TOCHNAGE!
|
rt300@25
|
39
|
rt300@9
|
40 // can add but don't change ordering - this will invalidate logs
|
rt300@25
|
41 enum leventType {SAVE_PRESET, // 0
|
rt300@25
|
42 SAVE_DESET, // 1
|
rt300@25
|
43 SCROLL, // 2
|
rt300@25
|
44 ZOOM, // 3
|
rt300@25
|
45 SCROLL_STOPPED, // 4
|
rt300@25
|
46 ZOOM_STOPPED, // 5
|
rt300@25
|
47 SNAPPED_TO_PRESET, // 6
|
rt300@25
|
48 CHANGE_SLIDER, // 7
|
rt300@25
|
49 SWAP_VIEW, // 8
|
rt300@25
|
50 SET_MIN_ZOOM, // 9
|
rt300@25
|
51 SET_MAX_ZOOM, // 10
|
rt300@25
|
52 RANDOMISE, // 11
|
rt300@25
|
53 APP_STARTED, // 12
|
rt300@25
|
54 APP_EXITED, // 13
|
rt300@25
|
55 CONSENT_DENIED, // 14
|
rt300@25
|
56 SEQ_LOCKED, // 15
|
rt300@25
|
57 SYNTH_LOCKED, // 16
|
rt300@25
|
58 PLAY_PRESSED, // 17
|
rt300@25
|
59 PAUSE_PRESSED}; // 18
|
rt300@1
|
60
|
rt300@8
|
61 //---------------------------------------------------------------------------
|
rt300@8
|
62
|
rt300@4
|
63 class lEvent{
|
rt300@5
|
64 public:
|
rt300@1
|
65 // try and make this as compact as possible.
|
rt300@4
|
66 leventType eventType;
|
rt300@1
|
67 double val1; // x coord, scale if zoom
|
rt300@1
|
68 double val2; // y coord, 0 if zoom
|
rt300@25
|
69 int sliderID; // xtra int
|
rt300@9
|
70 long long eventTime;
|
rt300@8
|
71 lEvent(leventType eType, double v1 = 0.0, double v2 = 0.0,int sID = 0){
|
rt300@5
|
72 eventType = eType;
|
rt300@5
|
73 val1 = v1;
|
rt300@5
|
74 val2 = v2;
|
rt300@5
|
75 sliderID = sID;
|
rt300@9
|
76
|
rt300@9
|
77 double timemsd = [NSDate timeIntervalSinceReferenceDate];
|
rt300@25
|
78 eventTime = (unsigned long long)(timemsd*1000) - APP_CREATION_TIME;
|
rt300@9
|
79
|
rt300@5
|
80 }
|
rt300@25
|
81
|
rt300@8
|
82 lEvent(const Json::Value &jevt){
|
rt300@9
|
83 // constructor takes "jsonToEvent" readfile function role
|
rt300@25
|
84 eventType = (leventType)jevt["eType"].asInt();
|
rt300@25
|
85 val1 = jevt["v1"].asDouble();
|
rt300@25
|
86 val2 = jevt["v2"].asDouble();
|
rt300@25
|
87 sliderID = jevt["sID"].asInt();
|
rt300@25
|
88 eventTime = jevt["eTime"].asLargestInt();
|
rt300@9
|
89
|
rt300@15
|
90 // TODO what happens if we try to read one that isn't there?
|
rt300@15
|
91
|
rt300@8
|
92 }
|
rt300@8
|
93 Json::Value eventToJson(){
|
rt300@8
|
94 Json::Value jevt;
|
rt300@25
|
95 jevt["eType"] = eventType;
|
rt300@25
|
96 // here: should give a certain number of sig figs?
|
rt300@25
|
97 jevt["v1"] = val1;
|
rt300@25
|
98 jevt["v2"] = val2;
|
rt300@25
|
99 jevt["sID"] = sliderID;
|
rt300@25
|
100 jevt["eTime"] = eventTime;
|
rt300@8
|
101 return jevt;
|
rt300@8
|
102 }
|
rt300@5
|
103 };
|
rt300@5
|
104 //---------------------------------------------------------------------------
|
rt300@8
|
105 // streams no longer used
|
rt300@5
|
106 inline istream& operator>>(istream & is, lEvent& e){
|
rt300@5
|
107 is.setf(ios_base::fixed,ios_base::floatfield);
|
rt300@5
|
108 is.precision(1);
|
rt300@4
|
109
|
rt300@5
|
110 char delim;
|
rt300@5
|
111 int eType;
|
rt300@0
|
112
|
rt300@5
|
113 is >> eType >> delim >> e.val1 >> delim >> e.val2 >> delim >> e.sliderID;
|
rt300@5
|
114
|
rt300@5
|
115 e.eventType = (leventType)eType;
|
rt300@5
|
116
|
rt300@5
|
117 return is;
|
rt300@5
|
118 }
|
rt300@4
|
119
|
rt300@5
|
120 //---------------------------------------------------------------------------
|
rt300@5
|
121 inline ostream& operator<<(ostream & os, const lEvent& e){
|
rt300@5
|
122 os.setf(ios_base::fixed,ios_base::floatfield);
|
rt300@5
|
123 os.precision(1);
|
rt300@5
|
124
|
rt300@5
|
125 os << e.eventType << ',' << e.val1 << ',' << e.val2 << ',' << e.sliderID << '\n';
|
rt300@5
|
126
|
rt300@5
|
127 return os;
|
rt300@7
|
128 }
|
rt300@5
|
129 //---------------------------------------------------------------------------
|
rt300@4
|
130
|
rt300@0
|
131 class EventLogger{
|
rt300@0
|
132 public:
|
rt300@25
|
133 int nextUploadNumber;
|
rt300@14
|
134 bool loggingEnabled;
|
rt300@22
|
135 bool serverConnectionOK;
|
rt300@25
|
136 bool consentGiven;
|
rt300@14
|
137 unsigned int deviceID; // unique get something from hardware??
|
rt300@25
|
138 unsigned int totalInteractionTime, savedInteractionTime, sessionTime, sessionStartTime;
|
rt300@14
|
139 string userName; // not unique
|
rt300@14
|
140
|
rt300@14
|
141 EventLogger();
|
rt300@14
|
142 void init();
|
rt300@14
|
143 void exitAndSave();
|
rt300@14
|
144 void setUsername(const char *u);
|
rt300@14
|
145 void logEvent(const leventType& evtType,const TwoVector& centre = TwoVector(), const double& scale = 1.0, const int& sliderID = -1, const double& sliderVal = 0.0);
|
rt300@22
|
146 void questionnaireAnswersObtained(vector<int> answers);
|
rt300@14
|
147
|
rt300@14
|
148 private:
|
rt300@0
|
149 // what we need...
|
rt300@0
|
150 /*
|
rt300@0
|
151 time, type, value
|
rt300@0
|
152 */
|
rt300@14
|
153
|
rt300@14
|
154
|
rt300@4
|
155 vector<lEvent> theEvents;
|
rt300@0
|
156
|
rt300@16
|
157
|
rt300@14
|
158 // values applicable to all events
|
rt300@14
|
159
|
rt300@14
|
160 unsigned int nextUploadQty;
|
rt300@14
|
161
|
rt300@8
|
162
|
rt300@22
|
163 ofxiPhoneDeviceType iOSdeviceType;
|
rt300@14
|
164
|
rt300@9
|
165 bool testConnection();
|
rt300@22
|
166 vector<int> questionnaireAnswers;
|
rt300@22
|
167 bool questionnaireCompleted;
|
rt300@22
|
168 bool questionnaireUploaded;
|
rt300@9
|
169
|
rt300@7
|
170 void checkLogFile();
|
rt300@22
|
171 bool uploadEventLog();
|
rt300@7
|
172 void firstEverAppOpen();
|
rt300@8
|
173 void readJsonToLog(const string &jsonFile);
|
rt300@22
|
174 bool uploadQuestionnaire();
|
rt300@22
|
175 bool sendToServer(string functionName, Json::Value jsonData);
|
rt300@8
|
176 Json::Value logsToJson();
|
rt300@22
|
177 Json::Value questionnaireToJson();
|
rt300@5
|
178 void printAll(){
|
rt300@5
|
179 cout << "ALL LOGGED EVENTS!: \n";
|
rt300@5
|
180 vector<lEvent>::iterator evIter;
|
rt300@5
|
181 for(evIter = theEvents.begin(); evIter < theEvents.end(); evIter++){
|
rt300@5
|
182 cout << *evIter;
|
rt300@5
|
183
|
rt300@5
|
184 }
|
rt300@5
|
185 };
|
rt300@0
|
186 };
|
rt300@0
|
187
|
rt300@0
|
188
|
rt300@8
|
189 //---------------------------------------------------------------------------
|
rt300@8
|
190
|
rt300@5
|
191
|
rt300@0
|
192 #endif /* defined(__oscSenderExample__eventLogger__) */
|