-
Notifications
You must be signed in to change notification settings - Fork 106
Expand file tree
/
Copy pathMain.cpp
More file actions
225 lines (171 loc) · 7.31 KB
/
Main.cpp
File metadata and controls
225 lines (171 loc) · 7.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <QDir>
#include <QApplication>
#include <QFileInfo>
//#include <QTextStream>
#include <QMessageBox>
#include "Common/Cpp/Concurrency/AsyncTask.h"
#include "Common/Cpp/Concurrency/FireForgetDispatcher.h"
#include "Common/Cpp/Exceptions.h"
#include "Common/Cpp/ImageResolution.h"
#include "StaticRegistration.h"
#include "CommonFramework/Tools/GlobalThreadPools.h"
#include "VideoPipeline/Backends/MediaServicesQt6.h"
#include "Globals.h"
#include "GlobalSettingsPanel.h"
#include "PersistentSettings.h"
#include "Tests/CommandLineTests.h"
#include "ErrorReports/ProgramDumper.h"
#include "ErrorReports/ErrorReports.h"
#include "Environment/HardwareValidation.h"
#include "Integrations/DiscordSettingsOption.h"
#include "Integrations/DiscordSocial/DiscordSocial.h"
#include "Integrations/DppIntegration/DppClient.h"
#include "Logging/Logger.h"
#include "Logging/OutputRedirector.h"
//#include "Tools/StatsDatabase.h"
//#include "Windows/DpiScaler.h"
#include "Startup/SetupSettings.h"
#include "Startup/NewVersionCheck.h"
#include "CommonFramework/VideoPipeline/Backends/CameraImplementations.h"
#include "CommonTools/OCR/OCR_RawOCR.h"
#include "ControllerInput/ControllerInput.h"
#include "Windows/MainWindow.h"
#include <iostream>
using std::cout;
using std::endl;
using namespace PokemonAutomation;
Q_DECLARE_METATYPE(std::string)
void set_working_directory(){
QString application_dir_path = qApp->applicationDirPath();
if (application_dir_path.endsWith(".app/Contents/MacOS")){
// a macOS bundle. Change working directory to the folder that hosts the .app folder.
QString app_bundle_path = application_dir_path.chopped(15);
QString base_folder_path = QFileInfo(app_bundle_path).dir().absolutePath();
QDir::setCurrent(base_folder_path);
}
}
namespace PokemonAutomation{
// This function is required by Common/Cpp/Logging/GlobalLogger.h:global_logger_raw() to initialize
// the global file logger.
// This function is called the first time `global_logger_raw()` is called to initialize the static
// local global file logger object.
// Note: in order to make sure `USER_FILE_PATH()` and `QCoreApplication::applicationName()` work
// correctly you need to define `QApplication` before `make_global_config()` is called.
FileLoggerConfig make_global_config(){
return FileLoggerConfig{
.file_path = USER_FILE_PATH() + QCoreApplication::applicationName().toStdString() + ".log",
};
}
}
int run_program(int argc, char *argv[]){
QApplication application(argc, argv);
GlobalOutputRedirector redirect_stdout(std::cout, "stdout", Color());
GlobalOutputRedirector redirect_stderr(std::cerr, "stderr", COLOR_RED);
Logger& logger = global_logger_tagged();
logger.log("================================================================================");
logger.log("Starting Program...");
qRegisterMetaType<size_t>("size_t");
qRegisterMetaType<uint8_t>("uint8_t");
qRegisterMetaType<std::string>("std::string");
qRegisterMetaType<Resolution>("Resolution");
#if defined(__linux) || defined(__APPLE__)
// By default Qt uses native menubar but this only works on Windows.
// We use menubar in our ButtonDiagram window to choose which controller's button mapping image to show.
// So we fix it by don't using native menubar on non-Windows OS.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
#endif
//#if QT_VERSION_MAJOR == 5 // AA_EnableHighDpiScaling is deprecated in Qt6
// QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//#endif
QDir().mkpath(QString::fromStdString(SETTINGS_PATH()));
QDir().mkpath(QString::fromStdString(SCREENSHOTS_PATH()));
// Preload all the cameras now so we don't hang the UI later on.
get_all_cameras();
// Several novice developers struggled to build and run the program due to missing Resources folder.
// Add this check to pop a message box when Resources folder is missing.
if (!check_resource_folder(logger)){
return 1;
}
// Read program settings from json file: SerialPrograms-Settings.json.
try{
if (!migrate_settings(logger, application.applicationName().toStdString() + "-Settings.json")){
return 1;
}
PERSISTENT_SETTINGS().read();
if (!migrate_stats(logger)){
return 1;
}
}catch (const FileException& error){
logger.log(error.message(), COLOR_RED);
}catch (const ParseException& error){
logger.log(error.message(), COLOR_RED);
}
for (size_t i = 0; i < argc; i++){
constexpr const char* force_run_tests = "--command-line-test-mode";
constexpr const char* command_line_test_folder = "--command-line-test-folder";
if (strcmp(argv[i], force_run_tests) == 0){
GlobalSettings::instance().COMMAND_LINE_TEST_MODE = true;
}
if (strcmp(argv[i], command_line_test_folder) == 0 && (i + 1 < argc)){
GlobalSettings::instance().COMMAND_LINE_TEST_FOLDER = argv[i + 1];
}
}
if (GlobalSettings::instance().COMMAND_LINE_TEST_MODE){
return run_command_line_tests();
}
// Check whether the hardware is powerful enough to run this program.
if (!check_hardware()){
return 1;
}
check_new_version(logger);
set_working_directory();
// Run this asynchronously to we don't block startup.
std::unique_ptr<AsyncTask> task = send_all_unsent_reports(logger, true);
Integration::DiscordIntegrationSettingsOption& discord_settings = GlobalSettings::instance().DISCORD->integration;
if (discord_settings.run_on_start){
#ifdef PA_DPP
Integration::DppClient::Client::instance().connect();
#endif
discord_settings.on_config_value_changed(nullptr);
}
#ifdef PA_SOCIAL_SDK
if (GlobalSettings::instance().RICH_PRESENCE){
Integration::DiscordSocialSDK::DiscordSocial::instance().run();
}
#endif
MainWindow w;
w.show();
w.raise(); // bring the window to front on macOS
set_permissions(w);
int ret = application.exec();
GlobalMediaServices::instance().stop();
return ret;
}
int main(int argc, char *argv[]){
#if 0
// Retrieve and store program name
set_program_path(argv[0]);
#endif
// So far, this is only needed on Mac where static initialization is fucked up.
PokemonAutomation::register_all_statics();
setup_crash_handler();
int ret = run_program(argc, argv);
// Write program settings back to the json file.
PERSISTENT_SETTINGS().write();
#ifdef PA_SOCIAL_SDK
Integration::DiscordSocialSDK::DiscordSocial::instance().stop();
#endif
#ifdef PA_DPP
Integration::DppClient::Client::instance().disconnect();
#endif
// Stop the controllers.
global_input_stop();
// Force stop the thread pool
PokemonAutomation::GlobalThreadPools::realtime_inference().stop();
PokemonAutomation::GlobalThreadPools::normal_inference().stop();
PokemonAutomation::global_dispatcher.stop();
// We must clear the OCR cache or it will crash on Linux when the library
// unloads before the cache is destructed from static memory.
OCR::clear_cache();
return ret;
}