Make Key press sim use SDL event watcher for key event grabbing.

Create a mutex for UI that will help make it possible to run handlers that update UI elements on seprate threads.

its far from perfect but should hold up for now.
This commit is contained in:
MatthewColvin 2023-10-02 20:41:42 -05:00
parent 3bd2b1a98a
commit 94d75fa4d5
7 changed files with 57 additions and 25 deletions

View file

@ -4,29 +4,27 @@
#include <memory>
KeyPressSim::KeyPressSim()
: mKeyGrabberThread([this] {
: mKeyHandlerThread([this] {
while (true) {
HandleKeyPresses();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}),
mKeyHandlerThread([this] {
while (true) {
GrabKeys();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}){};
}) {
SDL_AddEventWatch(KeyPressSim::GrabKeyImpl, this);
};
void KeyPressSim::GrabKeys() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
auto keyEventType = event.type == SDL_KEYDOWN ? KeyEvent::Type::Press
int KeyPressSim::GrabKeyImpl(void *aSelf, SDL_Event *aEvent) {
reinterpret_cast<KeyPressSim *>(aSelf)->GrabKeys(aEvent);
return 0;
}
void KeyPressSim::GrabKeys(SDL_Event *aEvent) {
if (aEvent->type == SDL_KEYDOWN || aEvent->type == SDL_KEYUP) {
auto keyEventType = aEvent->type == SDL_KEYDOWN ? KeyEvent::Type::Press
: KeyEvent::Type::Release;
const auto SDLK_key = event.key.keysym.sym;
if (KeyMap.count(SDLK_key) > 0) {
QueueKeyEvent(KeyEvent(KeyMap.at(SDLK_key), keyEventType));
}
const auto SDLK_key = aEvent->key.keysym.sym;
if (KeyMap.count(SDLK_key) > 0) {
QueueKeyEvent(KeyEvent(KeyMap.at(SDLK_key), keyEventType));
}
}
};

View file

@ -12,7 +12,9 @@ public:
KeyPressSim();
void GrabKeys();
static int GrabKeyImpl(void *aSelf, SDL_Event *aEvent);
void GrabKeys(SDL_Event *aEvent);
void HandleKeyPresses() override;
void QueueKeyEvent(KeyEvent aJustOccuredKeyEvent) override;

View file

@ -0,0 +1,11 @@
#pragma once
#include <mutex>
class LvglMutex {
public:
[[nodiscard]] static std::lock_guard<std::mutex> lockScope() {
return std::lock_guard<std::mutex>(mLvglMutex);
}
inline static std::mutex mLvglMutex;
};

View file

@ -1,4 +1,5 @@
#include "UIBase.hpp"
#include "LvglMutex.hpp"
using namespace UI;
@ -7,5 +8,8 @@ UIBase::UIBase(std::shared_ptr<HardwareAbstract> aHardware)
void UIBase::loopHandler() {
lv_timer_handler();
lv_task_handler();
{
auto lock = LvglMutex::lockScope();
lv_task_handler();
}
}

View file

@ -1,28 +1,34 @@
#include "UIElement.hpp"
#include "LvglMutex.hpp"
namespace UI {
UIElement::UIElement(lv_obj_t *aLvglSelf, ID aId)
: mLvglSelf(aLvglSelf), mId(aId) {
auto lock = LvglMutex::lockScope();
mLvglSelf->user_data = this;
}
UIElement::~UIElement() {
auto lock = LvglMutex::lockScope();
if (lv_obj_is_valid(mLvglSelf)) {
lv_obj_del(mLvglSelf);
}
}
void UIElement::AddElement(UIElement *anUIElement) {
auto lock = LvglMutex::lockScope();
lv_obj_set_parent(anUIElement->mLvglSelf, mLvglSelf);
}
bool UIElement::IsVisible() { return lv_obj_is_visible(mLvglSelf); }
void UIElement::SetWidth(lv_coord_t aWidth) {
auto lock = LvglMutex::lockScope();
lv_obj_set_width(mLvglSelf, aWidth);
}
void UIElement::SetHeight(lv_coord_t aHeight) {
auto lock = LvglMutex::lockScope();
lv_obj_set_height(mLvglSelf, aHeight);
}
@ -36,8 +42,14 @@ lv_coord_t UIElement::GetWidth() {
return lv_obj_get_width(mLvglSelf);
}
void UIElement::SetY(lv_coord_t aY) { lv_obj_set_y(mLvglSelf, aY); }
void UIElement::SetX(lv_coord_t aX) { lv_obj_set_x(mLvglSelf, aX); }
void UIElement::SetY(lv_coord_t aY) {
auto lock = LvglMutex::lockScope();
lv_obj_set_y(mLvglSelf, aY);
}
void UIElement::SetX(lv_coord_t aX) {
auto lock = LvglMutex::lockScope();
lv_obj_set_x(mLvglSelf, aX);
}
lv_coord_t UIElement::GetY() {
lv_obj_update_layout(mLvglSelf);
@ -60,6 +72,7 @@ void UIElement::SetVisiblity(bool aVisible) {
}
void UIElement::SetBgColor(lv_color_t aColor, lv_style_selector_t aStyle) {
auto lock = LvglMutex::lockScope();
lv_obj_set_style_bg_color(mLvglSelf, aColor, aStyle);
};

View file

@ -21,6 +21,9 @@ bool Tab::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
return mContent->KeyEvent(aKeyEvent);
}
void Tab::OnShow() { mContent->OnShow(); };
void Tab::OnHide() { mContent->OnHide(); };
/////////////////////TabView/////////////////////////////////////
TabView::TabView(ID aId)
@ -53,13 +56,11 @@ void TabView::HandleTabChange() {
// Notify the page that it is now showing and the other that the are now
// hidden
for (int i = 0; i < mTabs.size(); i++) {
auto content = mTabs[i]->TakeContent();
if (GetCurrentTabIdx() == i) {
content->OnShow();
mTabs[i]->OnShow();
} else {
content->OnHide();
mTabs[i]->OnHide();
}
mTabs[i]->GiveContent(std::move(content));
}
}

View file

@ -18,6 +18,9 @@ public:
bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
void OnShow() override;
void OnHide() override;
private:
Base::Ptr mContent;
};