From af78d5dbb8641bf38334d180cd56fc5d51f75315 Mon Sep 17 00:00:00 2001 From: Martin Vladic Date: Sat, 21 Mar 2020 12:10:47 +0100 Subject: [PATCH] improved touch responsiveness --- src/eez/gui/gui.cpp | 1 + src/eez/gui/touch.cpp | 161 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 142 insertions(+), 20 deletions(-) diff --git a/src/eez/gui/gui.cpp b/src/eez/gui/gui.cpp index 2a92c54e5..e8fd9647c 100644 --- a/src/eez/gui/gui.cpp +++ b/src/eez/gui/gui.cpp @@ -61,6 +61,7 @@ osMessageQId g_guiMessageQueueId; void startThread() { decompressAssets(); mcu::display::onThemeChanged(); + touch::init(); g_guiMessageQueueId = osMessageCreate(osMessageQ(g_guiMessageQueue), NULL); g_guiTaskHandle = osThreadCreate(osThread(g_guiTask), nullptr); } diff --git a/src/eez/gui/touch.cpp b/src/eez/gui/touch.cpp index c598cd442..0e701c580 100644 --- a/src/eez/gui/touch.cpp +++ b/src/eez/gui/touch.cpp @@ -27,23 +27,72 @@ namespace eez { namespace gui { namespace touch { -EventType g_eventType = EVENT_TYPE_TOUCH_NONE; +static EventType g_lastEventType = EVENT_TYPE_TOUCH_NONE; -int g_x; -int g_y; -bool g_pressed; +static int g_x = -1; +static int g_y = -1; +static bool g_pressed = false; -int g_calibratedX = -1; -int g_calibratedY = -1; -bool g_calibratedPressed; +static int g_calibratedX = -1; +static int g_calibratedY = -1; +static bool g_calibratedPressed = false; -int g_filteredX = -1; -int g_filteredY = -1; -bool g_filteredPressed; +static int g_filteredX = -1; +static int g_filteredY = -1; +static bool g_filteredPressed = false; //////////////////////////////////////////////////////////////////////////////// -void tick() { +EventType g_eventType = EVENT_TYPE_TOUCH_NONE; +int g_eventX = -1; +int g_eventY = -1; + +//////////////////////////////////////////////////////////////////////////////// + +#if defined(EEZ_PLATFORM_STM32) + +static const int EVENT_QUEUE_MAX_SIZE = 50; +struct Event { + EventType type; + int x; + int y; +}; +static Event g_eventQueue[EVENT_QUEUE_MAX_SIZE]; +static uint8_t g_eventQueueHead = 0; +static uint8_t g_eventQueueTail = 0; +static bool g_eventQueueFull; +osMutexId(g_eventQueueMutexId); +osMutexDef(g_eventQueueMutex); + +void mainLoop(const void *); + +#if defined(EEZ_PLATFORM_STM32) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wwrite-strings" +#endif + +osThreadDef(g_touchTask, mainLoop, osPriorityNormal, 0, 1024); + +#if defined(EEZ_PLATFORM_STM32) +#pragma GCC diagnostic pop +#endif + +void oneIter(); + +void mainLoop(const void *) { +#ifdef __EMSCRIPTEN__ + oneIter(); +#else + while (1) { + oneIter(); + osDelay(10); + } +#endif +} + +#endif + +void oneIter() { bool pressed; int x; int y; @@ -69,28 +118,100 @@ void tick() { #endif if (g_pressed) { - if (g_eventType == EVENT_TYPE_TOUCH_NONE || g_eventType == EVENT_TYPE_TOUCH_UP) { - g_eventType = EVENT_TYPE_TOUCH_DOWN; + if (g_lastEventType == EVENT_TYPE_TOUCH_NONE || g_lastEventType == EVENT_TYPE_TOUCH_UP) { + g_lastEventType = EVENT_TYPE_TOUCH_DOWN; } else { - if (g_eventType == EVENT_TYPE_TOUCH_DOWN) { - g_eventType = EVENT_TYPE_TOUCH_MOVE; + if (g_lastEventType == EVENT_TYPE_TOUCH_DOWN) { + g_lastEventType = EVENT_TYPE_TOUCH_MOVE; } } } else { - if (g_eventType == EVENT_TYPE_TOUCH_DOWN || g_eventType == EVENT_TYPE_TOUCH_MOVE) { - g_eventType = EVENT_TYPE_TOUCH_UP; - } else if (g_eventType == EVENT_TYPE_TOUCH_UP) { + if (g_lastEventType == EVENT_TYPE_TOUCH_DOWN || g_lastEventType == EVENT_TYPE_TOUCH_MOVE) { + g_lastEventType = EVENT_TYPE_TOUCH_UP; + } else if (g_lastEventType == EVENT_TYPE_TOUCH_UP) { + g_lastEventType = EVENT_TYPE_TOUCH_NONE; + } + } + +#if defined(EEZ_PLATFORM_STM32) + if (g_lastEventType != EVENT_TYPE_TOUCH_NONE) { + if (osMutexWait(g_eventQueueMutexId, 5) == osOK) { + if (g_eventQueueFull || g_eventQueueTail != g_eventQueueHead) { + uint32_t previousEventQueueHead = g_eventQueueHead == 0 ? EVENT_QUEUE_MAX_SIZE - 1 : g_eventQueueHead - 1; + Event &event = g_eventQueue[previousEventQueueHead]; + if (event.type == g_lastEventType) { + g_eventQueueHead = previousEventQueueHead; + } + } + + Event &event = g_eventQueue[g_eventQueueHead]; + + event.type = g_lastEventType; + event.x = g_x; + event.y = g_y; + + if (g_eventQueueFull) { + g_eventQueueTail = (g_eventQueueTail + 1) % EVENT_QUEUE_MAX_SIZE; + } + + g_eventQueueHead = (g_eventQueueHead + 1) % EVENT_QUEUE_MAX_SIZE; + + if (g_eventQueueHead == g_eventQueueTail) { + g_eventQueueFull = true; + } + + osMutexRelease(g_eventQueueMutexId); + } + } +#endif +} + +//////////////////////////////////////////////////////////////////////////////// + +void init() { +#if defined(EEZ_PLATFORM_STM32) + g_eventQueueMutexId = osMutexCreate(osMutex(g_eventQueueMutex)); + osThreadCreate(osThread(g_touchTask), nullptr); +#endif +} + +void tick() { +#if defined(EEZ_PLATFORM_STM32) + if (osMutexWait(g_eventQueueMutexId, 5) == osOK) { + if (g_eventQueueFull || g_eventQueueTail != g_eventQueueHead) { + Event &event = g_eventQueue[g_eventQueueTail]; + + g_eventType = event.type; + g_eventX = event.x; + g_eventY = event.y; + + g_eventQueueTail = (g_eventQueueTail + 1) % EVENT_QUEUE_MAX_SIZE; + g_eventQueueFull = false; + } else { g_eventType = EVENT_TYPE_TOUCH_NONE; + g_eventX = -1; + g_eventY = -1; } + + osMutexRelease(g_eventQueueMutexId); } +#endif + +#if defined(EEZ_PLATFORM_SIMULATOR) + oneIter(); + + g_eventType = g_lastEventType; + g_eventX = g_x; + g_eventY = g_y; +#endif } int getX() { - return g_x; + return g_eventX; } int getY() { - return g_y; + return g_eventY; } } // namespace touch