Use app::Task instead of raw threads on FilterPreview

We can use a thread pool (avoid creating/destroying threads) and we
can continue the same task running when the filter restart (there is
no need to stop/wait and restart, because the filter task keeps
calling the applyStep() function anyway).
This commit is contained in:
David Capello 2023-05-12 10:20:30 -03:00
parent 2369f36322
commit 87075296ed
3 changed files with 25 additions and 25 deletions

2
laf

@ -1 +1 @@
Subproject commit 41476b78d001b82a72cc6556164bc20954d75636
Subproject commit 41822911e4091503bf22071a5ce579c2e03d52eb

View File

@ -21,8 +21,6 @@
#include "ui/message.h"
#include "ui/widget.h"
#include <thread>
namespace app {
using namespace ui;
@ -32,8 +30,6 @@ FilterPreview::FilterPreview(FilterManagerImpl* filterMgr)
: Widget(kGenericWidget)
, m_filterMgr(filterMgr)
, m_timer(1, this)
, m_filterThread(nullptr)
, m_filterIsDone(false)
{
setVisible(false);
}
@ -67,27 +63,32 @@ void FilterPreview::stop()
ASSERT(m_filterMgr);
m_filterMgr->end();
}
m_timer.stop();
}
m_timer.stop();
if (m_filterThread) {
m_filterThread->join();
m_filterThread.reset();
if (m_filterTask.running()) {
m_filterTask.cancel();
m_filterTask.wait();
}
}
void FilterPreview::restartPreview()
{
stop();
std::scoped_lock lock(m_filterMgrMutex);
// Restart filter, timer, and task if needed (there is no need to
// restart the task if it's already running)
if (m_timer.isRunning()) {
ASSERT(m_filterMgr);
m_filterMgr->end();
}
m_filterMgr->beginForPreview();
m_filterIsDone = false;
m_timer.start();
m_filterThread.reset(
new std::thread([this]{ onFilterThread(); }));
if (!m_filterTask.running()) {
m_filterTask.run([this](base::task_token& token){
onFilterTask(token);
});
}
}
bool FilterPreview::onProcessMessage(Message* msg)
@ -112,7 +113,7 @@ bool FilterPreview::onProcessMessage(Message* msg)
std::scoped_lock lock(m_filterMgrMutex);
if (m_filterMgr) {
m_filterMgr->flush();
if (m_filterIsDone)
if (m_filterTask.completed())
m_timer.stop();
}
break;
@ -123,14 +124,13 @@ bool FilterPreview::onProcessMessage(Message* msg)
}
// This is executed in other thread.
void FilterPreview::onFilterThread()
void FilterPreview::onFilterTask(base::task_token& token)
{
bool running = true;
while (running) {
while (!token.canceled()) {
{
std::scoped_lock lock(m_filterMgrMutex);
m_filterIsDone = !m_filterMgr->applyStep();
running = (!m_filterIsDone && m_timer.isRunning());
if (!m_filterMgr->applyStep())
token.cancel();
}
base::this_thread::yield();
}

View File

@ -9,11 +9,11 @@
#define APP_COMMANDS_FILTERS_FILTER_PREVIEW_H_INCLUDED
#pragma once
#include "app/task.h"
#include "ui/timer.h"
#include "ui/widget.h"
#include <mutex>
#include <thread>
namespace app {
@ -34,12 +34,12 @@ namespace app {
bool onProcessMessage(ui::Message* msg) override;
private:
void onFilterThread();
void onFilterTask(base::task_token& token);
FilterManagerImpl* m_filterMgr;
ui::Timer m_timer;
std::mutex m_filterMgrMutex;
std::unique_ptr<std::thread> m_filterThread;
app::Task m_filterTask;
bool m_filterIsDone;
};