Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] GESTURE_DOUBLETAP, TAP_TIMEOUT and rgGetCurrentTime() issue. #3175

Closed
4 tasks done
ghost opened this issue Jul 15, 2023 · 1 comment
Closed
4 tasks done

[core] GESTURE_DOUBLETAP, TAP_TIMEOUT and rgGetCurrentTime() issue. #3175

ghost opened this issue Jul 15, 2023 · 1 comment

Comments

@ghost
Copy link

ghost commented Jul 15, 2023

  • I tested it on latest raylib version from master branch
  • I checked there is no similar issue already reported
  • I checked the documentation on the wiki
  • My code has no errors or misuse of raylib

Issue description

Unfortunately GESTURE_DOUBLETAP appears to have a timing issue on all platforms.

It appears that the problem is the TAP_TIMEOUT value (rgestures.h#L184). rgesture.h comments mention time being in milliseconds, but, in fact, it's all being handled in seconds from GetTime() (rgestures.h#L531) while using rgestures.h with raylib. So the inconsistency of GESTURE_DOUBLETAP was that it had an "open window" of 300 seconds instead of 300 milliseconds.

Proposed solution

The most straightforward solution (since rgGetCurrentTime() (rgestures.h#L526) is already returning the time in seconds) is to convert TAP_TIMEOUT to seconds (and also PINCH_TIMEOUT since we're already there, although it's not being used at the moment) and fix the rgesture.h comments to replace milliseconds with seconds.

For consistency, it's also necessary to adjust the rgGetCurrentTime() standalone implementations (rgestures.h#L530-L566) so they also return time in seconds.

Will send a PR with the proposed changes shortly.

Environment

Platform: Linux
Operating System: Linux Mint 21.1 (x86_64)
OpenGL version: 3.1 Mesa 22.0.5
GPU: Intel HD Graphics 3000

Platform: Android
Operating System: Android 5.1.1
OpenGL version: OpenGL ES 1.1/2.0
GPU: Mali-400

Issue Screenshot

img

Code Example

Minimal reproduction code to test the issue:

#include "raylib.h"

#if defined(PLATFORM_WEB)
    #include <emscripten/emscripten.h>
#endif

#define GESTURE_LOG_SIZE 20
char gestureLog[GESTURE_LOG_SIZE][12] = { "" };
int gestureLogIndex = GESTURE_LOG_SIZE;
int previousGesture = 0;
char const *GetGestureName(int i) {
   switch (i) {
      case 0:   return "None";        break;
      case 1:   return "Tap";         break;
      case 2:   return "Double Tap";  break;
      case 4:   return "Hold";        break;
      case 8:   return "Drag";        break;
      case 16:  return "Swipe Right"; break;
      case 32:  return "Swipe Left";  break;
      case 64:  return "Swipe Up";    break;
      case 128: return "Swipe Down";  break;
      case 256: return "Pinch In";    break;
      case 512: return "Pinch Out";   break;
      default:  return "Unknown";     break;
   }
}
int logMode = 1;
Rectangle logButton1 = {53, 7, 48, 26};
Rectangle logButton2 = {108, 7, 36, 26};
Vector2 gestureLogPosition = {10, 10};

void Update(void) {
    // Handling:
    int i, ii;
    const int currentGesture = GetGestureDetected();
    if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
        if (CheckCollisionPointRec(GetMousePosition(), logButton1)) {
            switch (logMode) {
              case 3:  logMode=2; break;
              case 2:  logMode=3; break;
              case 1:  logMode=0; break;
              default: logMode=1; break;
            }
        } else if (CheckCollisionPointRec(GetMousePosition(), logButton2)) {
            switch (logMode) {
              case 3:  logMode=1; break;
              case 2:  logMode=0; break;
              case 1:  logMode=3; break;
              default: logMode=2; break;
            }
        }
    }
    int fillLog = 0;
    if (currentGesture !=0) {
        if (logMode == 3) {        // 3 hides repeated events and hide hold events
            if ((currentGesture != 4 && currentGesture != previousGesture) || currentGesture < 3) { fillLog = 1; }
        } else if (logMode == 2) { // 2 shows repeated events but hide hold events
            if (currentGesture != 4) { fillLog = 1; }
        } else if (logMode == 1) { // 1 hides repeated events
            if (currentGesture != previousGesture) { fillLog = 1; }
        } else {                   // 0 shows repeated events
            fillLog = 1;
        }
    }
    if (fillLog) {
        previousGesture = currentGesture;
        if (gestureLogIndex <= 0) { gestureLogIndex = GESTURE_LOG_SIZE; }
        gestureLogIndex--;
        TextCopy(gestureLog[gestureLogIndex], GetGestureName(currentGesture));
    }

    // Drawing:
    BeginDrawing();
    ClearBackground(RAYWHITE);
    DrawText("Log", gestureLogPosition.x, gestureLogPosition.y, 20, BLACK);
    for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) {
        DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? MAROON : LIGHTGRAY));
    }
    Color logButton1Color, logButton2Color;
    switch (logMode) {
      case 3:  logButton1Color=MAROON; logButton2Color=MAROON; break;
      case 2:  logButton1Color=GRAY;   logButton2Color=MAROON; break;
      case 1:  logButton1Color=MAROON; logButton2Color=GRAY;   break;
      default: logButton1Color=GRAY;   logButton2Color=GRAY;   break;
    }
    DrawRectangleRec(logButton1, logButton1Color);
    DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
    DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
    DrawRectangleRec(logButton2, logButton2Color);
    DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
    DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
    EndDrawing();
}

int main(void) {
    InitWindow(400, 450, "Doubletap test");
    #if defined(PLATFORM_WEB)
        emscripten_set_main_loop(Update, 0, 1);
    #else
        SetTargetFPS(60);
        while (!WindowShouldClose()) Update();
    #endif
    CloseWindow();
    return 0;
}
@raysan5
Copy link
Owner

raysan5 commented Jul 16, 2023

@ubkp Thanks for the review! rgestures had not been reviewed in a long time and it required several improvements. Using seconds for time measures is the most standard and logic option, actually, it was already adopted for raylib long time ago.

@raysan5 raysan5 closed this as completed Jul 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant