Skip to content

Commit 083efac

Browse files
committed
squash all changes to ResourceDownloading
1 parent 9003470 commit 083efac

21 files changed

Lines changed: 2027 additions & 8 deletions

SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ GlobalSettings::GlobalSettings()
261261
PA_ADD_OPTION(TEMP_FOLDER);
262262
PA_ADD_OPTION(THEME);
263263
PA_ADD_OPTION(USE_PADDLE_OCR);
264+
PA_ADD_OPTION(RESOURCE_DOWNLOAD_TABLE);
264265
PA_ADD_OPTION(WINDOW_SIZE);
265266
PA_ADD_OPTION(LOG_WINDOW_SIZE);
266267
PA_ADD_OPTION(LOG_WINDOW_STARTUP);
@@ -446,6 +447,10 @@ void GlobalSettings::on_press(){
446447

447448

448449

450+
void GlobalSettings::update_resource_download_row_status(const std::string& resource_slug, bool success){
451+
RESOURCE_DOWNLOAD_TABLE.update_row_status(resource_slug, success);
452+
}
453+
449454

450455

451456

SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "Common/Cpp/Options/ButtonOption.h"
1818
#include "CommonFramework/Panels/SettingsPanel.h"
1919
#include "CommonFramework/Panels/PanelTools.h"
20+
#include "CommonFramework/ResourceDownload/ResourceDownloadTable.h"
2021

2122
//#include <iostream>
2223
//using std::cout;
@@ -111,6 +112,8 @@ class GlobalSettings : public BatchOption, private ConfigOption::Listener, priva
111112
virtual void load_json(const JsonValue& json) override;
112113
virtual JsonValue to_json() const override;
113114

115+
void update_resource_download_row_status(const std::string& resource_slug, bool success);
116+
114117
private:
115118
virtual void on_config_value_changed(void* object) override;
116119
virtual void on_press() override;
@@ -124,6 +127,7 @@ class GlobalSettings : public BatchOption, private ConfigOption::Listener, priva
124127

125128
Pimpl<ThemeSelectorOption> THEME;
126129
BooleanCheckBoxOption USE_PADDLE_OCR;
130+
ResourceDownloadTable RESOURCE_DOWNLOAD_TABLE;
127131
Pimpl<ResolutionOption> WINDOW_SIZE;
128132
Pimpl<ResolutionOption> LOG_WINDOW_SIZE;
129133
BooleanCheckBoxOption LOG_WINDOW_STARTUP;

SerialPrograms/Source/CommonFramework/ProgramSession.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ProgramSession::ProgramSession(const ProgramDescriptor& descriptor)
3434
, m_logger(global_logger_raw(), "Program")
3535
, m_timestamp(current_time())
3636
, m_state(ProgramState::STOPPED)
37+
, m_download_manager(descriptor.required_resources())
3738
{
3839
load_historical_stats();
3940
}

SerialPrograms/Source/CommonFramework/ProgramSession.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Common/Cpp/ListenerSet.h"
2323
#include "Common/Cpp/Concurrency/Mutex.h"
2424
#include "Common/Cpp/Concurrency/AsyncTask.h"
25+
#include "CommonFramework/ResourceDownload/RequiredDownloadManager.h"
2526
#include "CommonFramework/Globals.h"
2627
//#include "CommonFramework/Logging/Logger.h"
2728
#include "Integrations/ProgramTrackerInterfaces.h"
@@ -59,6 +60,7 @@ class ProgramSession : public TrackableProgram{
5960
const ProgramDescriptor& descriptor() const{ return m_descriptor; }
6061
uint64_t instance_id() const{ return m_instance_id; }
6162
Logger& logger(){ return m_logger; }
63+
RequiredDownloadManager& get_download_manager(){ return m_download_manager; }
6264

6365

6466
public:
@@ -140,6 +142,8 @@ class ProgramSession : public TrackableProgram{
140142
// CancellableScope* m_scope = nullptr;
141143

142144
ListenerSet<Listener> m_listeners;
145+
146+
RequiredDownloadManager m_download_manager;
143147
};
144148

145149

SerialPrograms/Source/CommonFramework/ResourceDownload/RequiredDownload.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ DownloadThread RequiredDownload::initialize_download_thread(){
3030
DownloadThread::Hooks generic_row_hooks{
3131
.is_ready_to_start = [this] { return m_download_manager.is_download_ready_to_start(m_name); },
3232
.on_finished = [this](bool success) {
33-
// GlobalSettings::instance().update_resource_download_row_status(m_index, success);
33+
GlobalSettings::instance().update_resource_download_row_status(m_name, success);
3434
on_download_finished();
3535
},
3636
.report_failed = [this] { report_download_failed(); },
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/* Required Download Dialog Widget
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include <QVBoxLayout>
8+
#include <QMessageBox>
9+
// #include <QFont>
10+
// #include <QObject>
11+
// #include <QPushButton>
12+
// #include <QPointer>
13+
// #include <QHBoxLayout>
14+
// #include "CommonFramework/Logging/Logger.h"
15+
#include "Common/Cpp/Exceptions.h"
16+
17+
// #include "CommonFramework/Notifications/ProgramNotifications.h"
18+
#include "RequiredDownloadDialogWidget.h"
19+
20+
#include <iostream>
21+
using std::cout;
22+
using std::endl;
23+
24+
namespace PokemonAutomation{
25+
26+
27+
////////////////////////////////////////////
28+
// RequiredDownloadWidget
29+
////////////////////////////////////////////
30+
31+
RequiredDownloadWidget::~RequiredDownloadWidget(){
32+
m_value->remove_listener(*this);
33+
}
34+
35+
RequiredDownloadWidget::RequiredDownloadWidget(QWidget& parent, std::shared_ptr<RequiredDownload> download_ptr)
36+
: QWidget(&parent)
37+
, m_value(download_ptr)
38+
{
39+
40+
QHBoxLayout* mainLayout = new QHBoxLayout(this);
41+
// Create a label for the specific task
42+
m_resource_name = new QLabel(QString::fromStdString(download_ptr->get_name()), this);
43+
m_resource_name->setFixedWidth(300);
44+
mainLayout->addWidget(m_resource_name);
45+
46+
// Create a label for the status
47+
m_status_label = new QLabel("", this);
48+
m_status_label->setFixedWidth(70);
49+
mainLayout->addWidget(m_status_label);
50+
51+
// Create the progress bar
52+
m_progress_bar = new QProgressBar(this);
53+
m_progress_bar->setRange(0, 100);
54+
m_progress_bar->setValue(0);
55+
m_progress_bar->setFixedWidth(100);
56+
mainLayout->addWidget(m_progress_bar);
57+
58+
download_ptr->add_listener(*this);
59+
}
60+
61+
62+
void RequiredDownloadWidget::update_progress_bar(uint64_t bytes_done, uint64_t total_bytes, const std::string& text){
63+
double percent = total_bytes > 0 ? (static_cast<double>(bytes_done) / total_bytes) * 100.0 : 0;
64+
int current_percent = static_cast<int>(percent);
65+
int last_percentage = m_progress_bar->value();
66+
// Only update UI if integer value has changed
67+
if (current_percent == last_percentage){
68+
return;
69+
}
70+
71+
// current_percent has changed. update the progress bar
72+
m_status_label->setText(QString::fromStdString(text));
73+
m_progress_bar->setValue(current_percent);
74+
}
75+
76+
void RequiredDownloadWidget::on_download_progress(uint64_t bytes_done, uint64_t total_bytes){
77+
QMetaObject::invokeMethod(this, [this, bytes_done, total_bytes]{
78+
update_progress_bar(bytes_done, total_bytes, "Downloading");
79+
}, Qt::QueuedConnection);
80+
}
81+
void RequiredDownloadWidget::on_unzip_progress(uint64_t bytes_done, uint64_t total_bytes){
82+
QMetaObject::invokeMethod(this, [this, bytes_done, total_bytes]{
83+
update_progress_bar(bytes_done, total_bytes, "Unzipping");
84+
}, Qt::QueuedConnection);
85+
}
86+
void RequiredDownloadWidget::on_hash_progress(uint64_t bytes_done, uint64_t total_bytes){
87+
QMetaObject::invokeMethod(this, [this, bytes_done, total_bytes]{
88+
update_progress_bar(bytes_done, total_bytes, "Verifying");
89+
}, Qt::QueuedConnection);
90+
}
91+
92+
void RequiredDownloadWidget::on_download_failed(){
93+
std::cerr << "Error: Download failed. Check your internet connection and check you have enough disk space." << std::endl;
94+
QMetaObject::invokeMethod(this, []{
95+
QMessageBox box;
96+
box.critical(nullptr, "Error",
97+
QString::fromStdString("Error: Download failed. Check your internet connection and check you have enough disk space."));
98+
});
99+
}
100+
101+
////////////////////////////////////////////
102+
// RequiredDownloadDialogWidget
103+
////////////////////////////////////////////
104+
105+
RequiredDownloadDialogWidget::~RequiredDownloadDialogWidget(){
106+
m_download_manager.remove_download_listener(*this);
107+
}
108+
RequiredDownloadDialogWidget::RequiredDownloadDialogWidget(QWidget& parent, RequiredDownloadManager& download_manager)
109+
: QDialog (&parent)
110+
, m_download_manager(download_manager)
111+
{
112+
setWindowTitle("Task Progress");
113+
resize(400, 50 * (int)download_manager.get_required_downloads().size() + 50); // Dynamically scale height
114+
115+
QVBoxLayout* mainLayout = new QVBoxLayout(this);
116+
117+
for (std::shared_ptr<RequiredDownload> download_ptr : download_manager.get_required_downloads()){
118+
// cout << download_ptr->get_name() << endl;
119+
120+
RequiredDownloadWidget* download_layout = new RequiredDownloadWidget(*this, download_ptr);
121+
download_ptr->start_download();
122+
123+
mainLayout->addWidget(download_layout);
124+
125+
// Add a small spacing gap between tasks
126+
mainLayout->addSpacing(0);
127+
}
128+
129+
// 2. Create standard Dialog Buttons (OK and Cancel)
130+
QDialogButtonBox* buttonBox = new QDialogButtonBox(
131+
QDialogButtonBox::Cancel,
132+
this
133+
);
134+
135+
// 3. Connect the buttons to the default QDialog slots
136+
// Clicking OK calls accept(), clicking Cancel calls reject()
137+
// connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
138+
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
139+
140+
// 4. Add the buttons to the bottom of the layout
141+
mainLayout->addWidget(buttonBox);
142+
setLayout(mainLayout);
143+
144+
download_manager.add_download_listener(*this);
145+
}
146+
147+
148+
void RequiredDownloadDialogWidget::on_all_downloads_finished(){
149+
cout << "All downloads finished. Start the program." << endl;
150+
QMetaObject::invokeMethod(this, [this](){
151+
this->accept();
152+
});
153+
}
154+
void RequiredDownloadDialogWidget::on_download_failed(){
155+
std::cerr << "Error: Download failed. Check your internet connection and check you have enough disk space." << std::endl;
156+
QMetaObject::invokeMethod(this, [this]{
157+
this->reject();
158+
QMessageBox box;
159+
box.critical(nullptr, "Error",
160+
QString::fromStdString("Error: Download failed. Check your internet connection and check you have enough disk space."));
161+
});
162+
163+
}
164+
void RequiredDownloadDialogWidget::on_exception_caught(const std::string& function_name){
165+
std::cerr << "Error: Exception thrown in thread. From " + function_name + ". Report this as a bug." << std::endl;
166+
QMetaObject::invokeMethod(this, [this, function_name]{
167+
this->reject();
168+
169+
QMessageBox box;
170+
box.critical(nullptr, "Error",
171+
QString::fromStdString("Error: Exception thrown in thread. From " + function_name + ". Report this as a bug."));
172+
});
173+
}
174+
175+
/////////////////////////
176+
// Non member functions
177+
/////////////////////////
178+
179+
180+
bool show_download_prereqs_popup(
181+
QWidget* parent,
182+
RequiredDownloadManager& download_manager,
183+
std::function<void(const std::string&)> error_callback
184+
){
185+
186+
try{
187+
188+
// RequiredDownloadManager& download_manager = m_session.get_download_manager();
189+
// re-initialize the required downloads, even if already initialized
190+
// this refreshes the download list, which may have changed since the last run
191+
download_manager.initialize_required_downloads();
192+
193+
if (download_manager.get_upgrade_warning()){
194+
std::string warning_string =
195+
"The program is expecting an older version of a resource than is available. "
196+
"This likely means that your version of Computer Control is out of date. "
197+
"We recommend that you upgrade the Computer Control program.";
198+
error_callback(warning_string);
199+
// cout << warning_string << endl;
200+
}
201+
if (download_manager.get_required_downloads().empty()){
202+
cout << "required_download_list is empty. Start the program." << endl;
203+
204+
return true;
205+
}
206+
207+
RequiredDownloadDialogWidget box{*parent, download_manager};
208+
209+
// box.open();
210+
if (box.exec() == QDialog::Accepted){
211+
cout << "Pre-req downloads done" << endl;
212+
return true;
213+
}else{
214+
cout << "Pre-req downloads NOT done." << endl;
215+
download_manager.cancel_downloads();
216+
return false;
217+
}
218+
219+
}catch(InternalProgramError& e){
220+
error_callback(e.message());
221+
}catch (const std::exception& e) {
222+
std::string message = std::string(e.what()) + "Report this as an error.";
223+
error_callback(message);
224+
}catch(...){
225+
error_callback("show_download_prereqs_popup: Unknown exception caught. Report this as an error.");
226+
}
227+
228+
return false;
229+
230+
}
231+
232+
233+
234+
235+
}

0 commit comments

Comments
 (0)