Skip to content

Commit

Permalink
improve: add deferEvent in dispatcher to fix UI Draw
Browse files Browse the repository at this point in the history
  • Loading branch information
mehah authored Dec 8, 2023
1 parent bc077c9 commit e131c7d
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 32 deletions.
38 changes: 33 additions & 5 deletions src/framework/core/eventdispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include "timer.h"

EventDispatcher g_dispatcher, g_textDispatcher, g_mainDispatcher;
std::thread::id g_mainThreadId = std::this_thread::get_id();
std::thread::id g_eventThreadId;
int16_t g_mainThreadId = EventDispatcher::getThreadId();
int16_t g_eventThreadId = -1;

void EventDispatcher::init() {
m_threads.reserve(g_asyncDispatcher.getNumberOfThreads() + 1);
Expand All @@ -45,6 +45,8 @@ void EventDispatcher::shutdown()
} while (!m_eventList.empty());

m_scheduledEventList.clear();
m_deferEventList.clear();
m_threads.clear();

m_disabled = true;
}
Expand All @@ -54,6 +56,7 @@ void EventDispatcher::poll()
mergeEvents();
executeEvents();
executeScheduledEvents();
executeDeferEvents();
}

void EventDispatcher::startEvent(const ScheduledEventPtr& event)
Expand Down Expand Up @@ -100,7 +103,7 @@ EventPtr EventDispatcher::addEvent(const std::function<void()>& callback)
if (m_disabled)
return std::make_shared<Event>(nullptr);

if (&g_mainDispatcher == this && g_mainThreadId == std::this_thread::get_id()) {
if (&g_mainDispatcher == this && g_mainThreadId == getThreadId()) {
callback();
return std::make_shared<Event>(nullptr);
}
Expand All @@ -110,17 +113,42 @@ EventPtr EventDispatcher::addEvent(const std::function<void()>& callback)
return thread->events.emplace_back(std::make_shared<Event>(callback));
}

void EventDispatcher::deferEvent(const std::function<void()>& callback) {
if (m_disabled)
return;

const auto& thread = getThreadTask();
std::scoped_lock lock(thread->mutex);
thread->deferEvents.emplace_back(callback);
}

void EventDispatcher::executeEvents() {
if (m_eventList.empty()) {
return;
}

for (const auto& event : m_eventList) {
for (const auto& event : m_eventList)
event->execute();
}

m_eventList.clear();
}

void EventDispatcher::executeDeferEvents() {
do {
for (auto& event : m_deferEventList)
event.execute();
m_deferEventList.clear();

for (const auto& thread : m_threads) {
std::scoped_lock lock(thread->mutex);
if (!thread->deferEvents.empty()) {
m_deferEventList.insert(m_deferEventList.end(), make_move_iterator(thread->deferEvents.begin()), make_move_iterator(thread->deferEvents.end()));
thread->deferEvents.clear();
}
}
} while (!m_deferEventList.empty());
}

void EventDispatcher::executeScheduledEvents() {
auto& threadScheduledTasks = getThreadTask()->scheduledEventList;

Expand Down
26 changes: 15 additions & 11 deletions src/framework/core/eventdispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,12 @@ class EventDispatcher
void poll();

EventPtr addEvent(const std::function<void()>& callback);
void deferEvent(const std::function<void()>& callback);
ScheduledEventPtr scheduleEvent(const std::function<void()>& callback, int delay);
ScheduledEventPtr cycleEvent(const std::function<void()>& callback, int delay);

void startEvent(const ScheduledEventPtr& event);

private:
inline void mergeEvents();
inline void executeEvents();
inline void executeScheduledEvents();

const auto& getThreadTask() const {
return m_threads[getThreadId()];
}

static int16_t getThreadId() {
static std::atomic_int16_t lastId = -1;
thread_local static int16_t id = -1;
Expand All @@ -66,6 +58,16 @@ class EventDispatcher
return id;
};

private:
inline void mergeEvents();
inline void executeEvents();
inline void executeDeferEvents();
inline void executeScheduledEvents();

const auto& getThreadTask() const {
return m_threads[getThreadId()];
}

size_t m_pollEventsSize{};
bool m_disabled{ false };

Expand All @@ -78,16 +80,18 @@ class EventDispatcher
}

std::vector<EventPtr> events;
std::vector<Event> deferEvents;
std::vector<ScheduledEventPtr> scheduledEventList;
std::mutex mutex;
};
std::vector<std::unique_ptr<ThreadTask>> m_threads;

// Main Events
std::vector<EventPtr> m_eventList;
std::vector<Event> m_deferEventList;
phmap::btree_multiset<ScheduledEventPtr, ScheduledEvent::Compare> m_scheduledEventList;
};

extern EventDispatcher g_dispatcher, g_textDispatcher, g_mainDispatcher;
extern std::thread::id g_mainThreadId;
extern std::thread::id g_eventThreadId;
extern int16_t g_mainThreadId;
extern int16_t g_eventThreadId;
2 changes: 1 addition & 1 deletion src/framework/core/graphicalapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void GraphicalApplication::run()

// THREAD - POOL & MAP
g_asyncDispatcher.dispatch([&] {
g_eventThreadId = std::this_thread::get_id();
g_eventThreadId = EventDispatcher::getThreadId();
while (!m_stopping) {
poll();

Expand Down
4 changes: 2 additions & 2 deletions src/framework/core/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void Logger::log(Fw::LogLevel level, const std::string_view message)
if (s_ignoreLogs)
return;

if (g_eventThreadId != std::this_thread::get_id()) {
if (g_eventThreadId > -1 && g_eventThreadId != EventDispatcher::getThreadId()) {
g_dispatcher.addEvent([this, level, msg = std::string{ message }] {
log(level, msg);
});
Expand Down Expand Up @@ -110,7 +110,7 @@ void Logger::log(Fw::LogLevel level, const std::string_view message)

void Logger::logFunc(Fw::LogLevel level, const std::string_view message, const std::string_view prettyFunction)
{
if (g_eventThreadId != std::this_thread::get_id()) {
if (g_eventThreadId > -1 && g_eventThreadId != EventDispatcher::getThreadId()) {
g_dispatcher.addEvent([this, level, msg = std::string{ message }, prettyFunction = std::string{ prettyFunction }] {
logFunc(level, msg, prettyFunction);
});
Expand Down
2 changes: 1 addition & 1 deletion src/framework/ui/uigridlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ bool UIGridLayout::internalUpdate()

if (m_fitChildren && preferredHeight != parentWidget->getHeight()) {
// must set the preferred height later
g_dispatcher.addEvent([=] {
g_dispatcher.deferEvent([=] {
parentWidget->setHeight(preferredHeight);
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/framework/ui/uihorizontallayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ bool UIHorizontalLayout::internalUpdate()

if (m_fitChildren && preferredWidth != parentWidget->getWidth()) {
// must set the preferred width later
g_dispatcher.addEvent([=] {
g_dispatcher.deferEvent([=] {
parentWidget->setWidth(preferredWidth);
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/framework/ui/uilayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void UILayout::updateLater()
return;

auto self = static_self_cast<UILayout>();
g_dispatcher.addEvent([self] {
g_dispatcher.deferEvent([self] {
self->m_updateScheduled = false;
self->update();
});
Expand Down
4 changes: 2 additions & 2 deletions src/framework/ui/uimanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ void UIManager::updateHoveredWidget(bool now)
func();
else {
m_hoverUpdateScheduled = true;
g_dispatcher.addEvent(func);
g_dispatcher.deferEvent(func);
}
}

Expand Down Expand Up @@ -600,4 +600,4 @@ UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const

widget->callLuaField("onSetup");
return widget;
}
}
2 changes: 1 addition & 1 deletion src/framework/ui/uiverticallayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ bool UIVerticalLayout::internalUpdate()

if (m_fitChildren && preferredHeight != parentWidget->getHeight()) {
// must set the preferred width later
g_dispatcher.addEvent([=] {
g_dispatcher.deferEvent([=] {
parentWidget->setHeight(preferredHeight);
});
}
Expand Down
12 changes: 6 additions & 6 deletions src/framework/ui/uiwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void UIWidget::drawChildren(const Rect& visibleRect, DrawPoolType drawPane)

// debug draw box
if (g_ui.isDrawingDebugBoxes() && drawPane == DrawPoolType::FOREGROUND) {
if(child->isFocused())
if (child->isFocused())
g_drawPool.addBoundingRect(child->getRect(), Color::yellow);
else
g_drawPool.addBoundingRect(child->getRect(), Color::green);
Expand Down Expand Up @@ -1046,7 +1046,7 @@ bool UIWidget::setRect(const Rect& rect)
// avoid massive update events
if (!hasProp(PropUpdateEventScheduled)) {
auto self = static_self_cast<UIWidget>();
g_dispatcher.addEvent([self, oldRect] {
g_dispatcher.deferEvent([self, oldRect] {
self->setProp(PropUpdateEventScheduled, false);
const auto& rect = self->getRect();
if (oldRect != rect) {
Expand Down Expand Up @@ -1625,7 +1625,7 @@ void UIWidget::updateStyle()

if (hasProp(PropLoadingStyle) && !hasProp(PropUpdateStyleScheduled)) {
UIWidgetPtr self = static_self_cast<UIWidget>();
g_dispatcher.addEvent([self] {
g_dispatcher.deferEvent([self] {
self->setProp(PropUpdateStyleScheduled, false);
self->updateStyle();
});
Expand Down Expand Up @@ -1819,7 +1819,7 @@ bool UIWidget::onDoubleClick(const Point& mousePos)
return callLuaField<bool>("onDoubleClick", mousePos);
}

UIWidgetPtr UIWidget::getHoveredChild()
UIWidgetPtr UIWidget::getHoveredChild()
{
const auto& hovered = g_ui.getHoveredWidget();
return hovered ? getChildById(hovered->getId()) : nullptr;
Expand Down Expand Up @@ -1958,7 +1958,7 @@ void UIWidget::move(int x, int y) {

if (!hasProp(PropUpdatingMove)) {
setProp(PropUpdatingMove, true);
g_dispatcher.addEvent([self = static_self_cast<UIWidget>()] {
g_dispatcher.deferEvent([self = static_self_cast<UIWidget>()] {
const auto rect = self->m_rect;
self->m_rect = {}; // force update
self->setRect(rect);
Expand All @@ -1980,4 +1980,4 @@ void UIWidget::setShader(const std::string_view name) {
});
}

void UIWidget::repaint() { g_app.repaint(); }
void UIWidget::repaint() { g_app.repaint(); }
2 changes: 1 addition & 1 deletion src/framework/ui/uiwidgetbasestyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,4 @@ void UIWidget::setIcon(const std::string& iconFile)

repaint();
});
}
}

0 comments on commit e131c7d

Please sign in to comment.