//========================== // KeyState::Update KeyEventType KeyState::Update( double const time ) { //LOG_WITH_TAG( "KeyState", "Update: NumEvents %i", NumEvents ); if ( NumEvents > 0 ) { // is long-press time expired? This will always trigger a long press, even if the button // is let up on the same frame that we exceed the long press timer. if ( NumEvents != 2 && time - EventTimes[0] >= LongPressTime ) { Reset(); LOG_WITH_TAG( "KeyState", "(%.4f) Update() - KEY_EVENT_LONG_PRESS, %i", vrapi_GetTimeInSeconds(), NumEvents ); return KEY_EVENT_LONG_PRESS; } if ( NumEvents == 2 ) { // we've had a down ---> up sequence. if ( time - EventTimes[0] > DoubleTapTime ) { // Only send a short press if the button went down once and up in less than the double-tap time. if ( EventTimes[1] - EventTimes[0] < DoubleTapTime ) { // the HMT button always releases a hold at 0.8 seconds right now :( LOG_WITH_TAG( "KeyState", "(%.4f) Update() - press released after %.2f seconds.", vrapi_GetTimeInSeconds(), time - EventTimes[0] ); Reset(); return KEY_EVENT_SHORT_PRESS; } else { LOG_WITH_TAG( "KeyState", "(%.4f) Update() - discarding short-press after %.2f seconds.", vrapi_GetTimeInSeconds(), time - EventTimes[0] ); Reset(); return KEY_EVENT_UP; } } } } KeyEventType outEvent = PendingEvent; PendingEvent = KEY_EVENT_NONE; if ( outEvent != KEY_EVENT_NONE ) { LOG_WITH_TAG( "KeyState", "outEvent %s", KeyEventNames[ outEvent ] ); } return outEvent; }
//========================== // KeyState::HandleEvent void KeyState::HandleEvent( double const time, bool const down, int const repeatCount ) { LOG_WITH_TAG( "KeyState", "(%.4f) HandleEvent: %s, NumEvents %i, RepeatCount %i", vrapi_GetTimeInSeconds(), down ? "DOWN" : "UP", NumEvents, repeatCount ); bool wasDown = this->Down; this->Down = down; if ( NumEvents <= 0 && !down ) { // we ignore up events if we aren't currently tracking from a down -- this let's us exclude the up // event after a long press because we Reset() as soon as we fire the long-press event. PendingEvent = KEY_EVENT_NONE; return; } if ( repeatCount > 0 ) { ASSERT_WITH_TAG( down == true, "KeyState" ); // only a hold should have a repeat count // key is held PendingEvent = KEY_EVENT_NONE; return; } if ( wasDown == down ) { LOG_WITH_TAG( "KeyState", "wasDown != down" ); // this should always be a toggle unless we've missed an event, right? PendingEvent = KEY_EVENT_NONE; return; } // record the event times if ( NumEvents < MAX_EVENTS ) { EventTimes[NumEvents++] = time; } if ( !down ) { if ( NumEvents == 2 ) { // the button was held longer than a double-tap time, but came up before the long-press time if ( time - EventTimes[0] > DoubleTapTime ) { // returning a short-press here allows a kinda-long-press to act as a short press, which // is fairly annoying if the user is just trying to abort a long press before the menu appears. //PendingEvent = KEY_EVENT_SHORT_PRESS; PendingEvent = KEY_EVENT_UP; return; } else { // coming up for the first time PendingEvent = KEY_EVENT_UP; return; } } } else { // key going down if ( NumEvents == 1 && repeatCount == 0 ) { PendingEvent = KEY_EVENT_DOWN; // initial down event return; } if ( NumEvents == 3 ) // second down event { if ( time - EventTimes[0] <= DoubleTapTime ) { Reset(); PendingEvent = KEY_EVENT_DOUBLE_TAP; return; } } } PendingEvent = KEY_EVENT_NONE; }
void setLogFile(const char *fileName) { if (fileName == NULL) { return; } if (strlen(fileName) == 0) { return; } if (strlen(fileName) > MAX_LOG_FILE_NAME_LEN - 1) { printf("too long file name:%d\n",strlen(fileName)); return; } { FILE *f = NULL; #if __IS_WIN__ if ((fopen_s(&f,fileName,"rw")) != 0) { #else if ((f = fopen(fileName,"rw")) == NULL) { #endif printf("open log file [%s] error\n",fileName); return; } fclose(f); #if __IS_WIN__ strncpy_s(logFileName,MAX_LOG_FILE_NAME_LEN,fileName,strlen(fileName)); #else strncpy(logFileName,fileName,MAX_LOG_FILE_NAME_LEN); #endif } } void printLog(char* sModule, int nLogLevel, char *sFile,int nLine,char *fmt, ...) { struct tm newTimeST; #if __IS_WIN__ DWORD nThreadID; #else unsigned int nThreadID; #endif struct tm *newtime = &newTimeST; time_t aclock; FILE *logFile = NULL; va_list ap1, ap2;; if (nLogLevel < 1 || nLogLevel > COUNT_ERROR_LEVEL) { printf("error log level:%d\n",nLogLevel); return; } if (nLogLevel > logLevel) { return; } time( &aclock ); #if __IS_WIN__ localtime_s(newtime, &aclock ); nThreadID = GetCurrentProcessId(); nThreadID = (nThreadID << 16) + GetCurrentThreadId(); #else newtime = localtime( &aclock ); nThreadID = getpid(); nThreadID = (nThreadID << 16) + pthread_self(); #endif if (strlen(logFileName) > 0) { #if __IS_WIN__ if ((fopen_s(&logFile,logFileName,"rb+")) != 0) { #else if ((logFile = fopen(logFileName,"rb+")) == NULL) { #endif printf("open log file [%s] error\n",logFileName); } } printf("\n[%4d-%02d-%02d %02d:%02d:%02d][%s][%ud][%s:%d][%s] ", newtime->tm_year+1900,newtime->tm_mon+1,newtime->tm_mday,newtime->tm_hour, newtime->tm_min,newtime->tm_sec,sModule,nThreadID,sFile,nLine,errorLevel[nLogLevel-1]); va_start(ap1, fmt); if (logFile != NULL) { #if __IS_WIN__ ap2 = ap1; #else va_copy(ap2, ap1); #endif vfprintf(logFile,fmt,ap2); } vprintf(fmt,ap1); if (logFile != NULL) { va_end(ap2); } va_end(ap1); } int errorReturn(int errorCode,char *tag,char *msg) { LOG_WITH_TAG(LEVEL_ERROR,tag,errorCode,msg); return errorCode; }