commit 2d14d6f81fdbd123375a71462b2f1e58b34f8596
parent 492e40e9b069b751deec9e6b0cba5ddb88a5d472
Author: cfillion <cfillion@users.noreply.github.com>
Date: Fri, 4 Mar 2016 01:16:09 -0500
give the download queue to the progress dialog instead of giving it the transaction
and don't keep the progress dialog in memory longer than necessary
Diffstat:
7 files changed, 47 insertions(+), 60 deletions(-)
diff --git a/src/download.cpp b/src/download.cpp
@@ -295,6 +295,10 @@ void Download::abort()
DownloadQueue::~DownloadQueue()
{
+ // don't emit DownloadQueue::onAbort from the destructor
+ // which is most likely to cause a crash
+ m_onAbort.disconnect_all_slots();
+
abort();
}
@@ -312,7 +316,7 @@ void DownloadQueue::push(Download *dl)
delete dl;
if(idle())
- m_onDone(nullptr);
+ m_onDone();
});
m_queue.push(dl);
@@ -337,6 +341,8 @@ void DownloadQueue::abort()
dl->abort();
clear();
+
+ m_onAbort();
}
void DownloadQueue::clear()
diff --git a/src/download.hpp b/src/download.hpp
@@ -99,8 +99,10 @@ private:
class DownloadQueue {
public:
- typedef boost::signals2::signal<void (Download *)> Signal;
- typedef Signal::slot_type Callback;
+ typedef boost::signals2::signal<void (Download *)> DlSignal;
+ typedef DlSignal::slot_type DlCallback;
+ typedef boost::signals2::signal<void ()> VoidSignal;
+ typedef VoidSignal::slot_type VoidCallback;
DownloadQueue() {}
DownloadQueue(const DownloadQueue &) = delete;
@@ -112,8 +114,9 @@ public:
bool idle() const { return m_queue.empty() && m_running.empty(); }
- void onPush(const Callback &callback) { m_onPush.connect(callback); }
- void onDone(const Callback &callback) { m_onDone.connect(callback); }
+ void onPush(const DlCallback &callback) { m_onPush.connect(callback); }
+ void onAbort(const VoidCallback &callback) { m_onAbort.connect(callback); }
+ void onDone(const VoidCallback &callback) { m_onDone.connect(callback); }
private:
void clear();
@@ -121,8 +124,9 @@ private:
Download::Queue m_queue;
std::vector<Download *> m_running;
- Signal m_onPush;
- Signal m_onDone;
+ DlSignal m_onPush;
+ VoidSignal m_onAbort;
+ VoidSignal m_onDone;
};
#endif
diff --git a/src/progress.cpp b/src/progress.cpp
@@ -23,44 +23,27 @@
using namespace std;
-Progress::Progress()
+Progress::Progress(DownloadQueue *queue)
: Dialog(IDD_PROGRESS_DIALOG),
- m_transaction(nullptr), m_label(nullptr), m_progress(nullptr),
+ m_queue(queue), m_label(nullptr), m_progress(nullptr),
m_done(0), m_total(0)
{
-}
-
-void Progress::setTransaction(Transaction *t)
-{
- m_transaction = t;
-
- m_done = 0;
- m_total = 0;
- m_currentName.clear();
-
- if(!m_transaction) {
- hide();
- return;
- }
-
- SetWindowText(m_label, AUTO_STR("Initializing..."));
-
- m_transaction->downloadQueue()->onPush(
- bind(&Progress::addDownload, this, placeholders::_1));
+ m_queue->onPush(bind(&Progress::addDownload, this, placeholders::_1));
}
void Progress::onInit()
{
m_label = getControl(IDC_LABEL);
m_progress = GetDlgItem(handle(), IDC_PROGRESS);
+
+ SetWindowText(m_label, AUTO_STR("Initializing..."));
}
void Progress::onCommand(const int id)
{
switch(id) {
case IDCANCEL:
- if(m_transaction)
- m_transaction->cancel();
+ m_queue->abort();
// don't wait until the current downloads are finished
// before getting out of the user way
@@ -74,10 +57,10 @@ void Progress::addDownload(Download *dl)
m_total++;
updateProgress();
- dl->onStart([=] {
- if(!isVisible())
- show();
+ if(!isVisible())
+ show();
+ dl->onStart([=] {
m_currentName = make_autostring(dl->name());
updateProgress();
});
diff --git a/src/progress.hpp b/src/progress.hpp
@@ -23,13 +23,11 @@
#include "encoding.hpp"
class Download;
-class Transaction;
+class DownloadQueue;
class Progress : public Dialog {
public:
- Progress();
-
- void setTransaction(Transaction *t);
+ Progress(DownloadQueue *);
protected:
void onInit() override;
@@ -39,7 +37,7 @@ private:
void addDownload(Download *);
void updateProgress();
- Transaction *m_transaction;
+ DownloadQueue *m_queue;
auto_string m_currentName;
HWND m_label;
diff --git a/src/reapack.cpp b/src/reapack.cpp
@@ -61,8 +61,8 @@ static void CleanupTempFiles()
ReaPack::ReaPack(REAPER_PLUGIN_HINSTANCE instance)
: syncAction(), importAction(), configAction(),
- m_transaction(nullptr), m_manager(nullptr), m_import(nullptr),
- m_instance(instance)
+ m_transaction(nullptr), m_progress(nullptr), m_manager(nullptr),
+ m_import(nullptr), m_instance(instance)
{
m_mainWindow = GetMainHwnd();
m_useRootPath = new UseRootPath(GetResourcePath());
@@ -74,8 +74,6 @@ ReaPack::ReaPack(REAPER_PLUGIN_HINSTANCE instance)
m_config = new Config;
m_config->read(Path::prefixRoot(Path::CONFIG_FILE));
- m_progress = Dialog::Create<Progress>(m_instance, m_mainWindow);
-
if(m_config->isFirstRun())
manageRemotes();
@@ -339,11 +337,13 @@ Transaction *ReaPack::createTransaction()
return nullptr;
}
- m_progress->setTransaction(m_transaction);
+ assert(!m_progress);
+ m_progress = Dialog::Create<Progress>(m_instance, m_mainWindow,
+ m_transaction->downloadQueue());
m_transaction->onFinish([=] {
- // hide the progress dialog
- m_progress->setTransaction(nullptr);
+ Dialog::Destroy(m_progress);
+ m_progress = nullptr;
if(!m_transaction->isReportEnabled())
return;
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -35,7 +35,17 @@ Transaction::Transaction()
{
m_registry = new Registry(Path::prefixCache(Path::REGISTRY_FILE));
- m_downloadQueue.onDone([=](void *) {
+ m_downloadQueue.onAbort([=] {
+ m_isCancelled = true;
+
+ for(Task *task : m_tasks)
+ task->rollback();
+
+ if(m_downloadQueue.idle())
+ finish();
+ });
+
+ m_downloadQueue.onDone([=] {
if(m_installQueue.empty())
finish();
else
@@ -248,19 +258,6 @@ void Transaction::uninstall(const Remote &remote)
addTask(task);
}
-void Transaction::cancel()
-{
- m_isCancelled = true;
-
- for(Task *task : m_tasks)
- task->rollback();
-
- if(m_downloadQueue.idle())
- finish();
- else
- m_downloadQueue.abort();
-}
-
bool Transaction::saveFile(Download *dl, const Path &path)
{
if(dl->state() != Download::Success) {
diff --git a/src/transaction.hpp b/src/transaction.hpp
@@ -62,7 +62,6 @@ public:
void registerAll(const Remote &);
void unregisterAll(const Remote &);
void runTasks();
- void cancel();
bool isCancelled() const { return m_isCancelled; }
bool isReportEnabled() const { return m_enableReport && !m_isCancelled; }