mirror of https://github.com/WerWolv/ImHex.git
sys: Improved startup time by running startup tasks in parallel
This commit is contained in:
parent
7b61268f22
commit
4c01a749de
|
@ -171,6 +171,8 @@ namespace hex {
|
||||||
void setGPUVendor(const std::string &vendor);
|
void setGPUVendor(const std::string &vendor);
|
||||||
|
|
||||||
void setPortableVersion(bool enabled);
|
void setPortableVersion(bool enabled);
|
||||||
|
|
||||||
|
void addInitArgument(const std::string &key, const std::string &value = { });
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgramArguments {
|
struct ProgramArguments {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <hex.hpp>
|
#include <hex.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <fmt/color.h>
|
#include <fmt/color.h>
|
||||||
|
@ -30,6 +31,9 @@ namespace hex::log {
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
[[maybe_unused]] void print(const fmt::text_style &ts, const std::string &level, const std::string &fmt, auto... args) {
|
[[maybe_unused]] void print(const fmt::text_style &ts, const std::string &level, const std::string &fmt, auto... args) {
|
||||||
|
static std::mutex logMutex;
|
||||||
|
std::scoped_lock lock(logMutex);
|
||||||
|
|
||||||
auto dest = getDestination();
|
auto dest = getDestination();
|
||||||
|
|
||||||
printPrefix(dest, ts, level);
|
printPrefix(dest, ts, level);
|
||||||
|
|
|
@ -385,6 +385,13 @@ namespace hex {
|
||||||
s_portableVersion = enabled;
|
s_portableVersion = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addInitArgument(const std::string &key, const std::string &value) {
|
||||||
|
static std::mutex initArgumentsMutex;
|
||||||
|
std::scoped_lock lock(initArgumentsMutex);
|
||||||
|
|
||||||
|
getInitArguments()[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ namespace hex::init {
|
||||||
|
|
||||||
bool loop();
|
bool loop();
|
||||||
|
|
||||||
void addStartupTask(const std::string &taskName, const TaskFunction &task) {
|
void addStartupTask(const std::string &taskName, const TaskFunction &task, bool async) {
|
||||||
this->m_tasks.emplace_back(taskName, task);
|
this->m_tasks.emplace_back(taskName, task, async);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -37,7 +37,7 @@ namespace hex::init {
|
||||||
|
|
||||||
std::future<bool> processTasksAsync();
|
std::future<bool> processTasksAsync();
|
||||||
|
|
||||||
std::vector<std::pair<std::string, TaskFunction>> m_tasks;
|
std::vector<std::tuple<std::string, TaskFunction, bool>> m_tasks;
|
||||||
|
|
||||||
std::string m_gpuVendor;
|
std::string m_gpuVendor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace hex::init {
|
||||||
struct Task {
|
struct Task {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::function<bool()> function;
|
std::function<bool()> function;
|
||||||
|
bool async;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Task> getInitTasks();
|
std::vector<Task> getInitTasks();
|
||||||
|
|
|
@ -43,15 +43,27 @@ namespace hex::init {
|
||||||
return std::async(std::launch::async, [this] {
|
return std::async(std::launch::async, [this] {
|
||||||
bool status = true;
|
bool status = true;
|
||||||
|
|
||||||
for (const auto &[name, task] : this->m_tasks) {
|
u32 tasksCompleted = 0;
|
||||||
{
|
for (const auto &[name, task, async] : this->m_tasks) {
|
||||||
|
if (!async) {
|
||||||
std::lock_guard guard(this->m_progressMutex);
|
std::lock_guard guard(this->m_progressMutex);
|
||||||
this->m_currTaskName = name;
|
this->m_currTaskName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
auto runTask = [&, task = task] {
|
||||||
if (!task())
|
if (!task())
|
||||||
status = false;
|
status = false;
|
||||||
|
|
||||||
|
tasksCompleted++;
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (async) {
|
||||||
|
std::thread(runTask).detach();
|
||||||
|
} else {
|
||||||
|
runTask();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
log::error("Init task '{}' threw an exception: {}", name, e.what());
|
log::error("Init task '{}' threw an exception: {}", name, e.what());
|
||||||
status = false;
|
status = false;
|
||||||
|
@ -63,6 +75,9 @@ namespace hex::init {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (tasksCompleted < this->m_tasks.size())
|
||||||
|
std::this_thread::sleep_for(100ms);
|
||||||
|
|
||||||
// Small extra delay so the last progress step is visible
|
// Small extra delay so the last progress step is visible
|
||||||
std::this_thread::sleep_for(200ms);
|
std::this_thread::sleep_for(200ms);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace hex::init {
|
||||||
auto latestVersion = releases.body["tag_name"].get<std::string_view>();
|
auto latestVersion = releases.body["tag_name"].get<std::string_view>();
|
||||||
|
|
||||||
if (latestVersion != currVersion)
|
if (latestVersion != currVersion)
|
||||||
ImHexApi::System::getInitArguments().insert({ "update-available", latestVersion.data() });
|
ImHexApi::System::impl::addInitArgument("update-available", latestVersion.data());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ namespace hex::init {
|
||||||
if (tip.code != 200)
|
if (tip.code != 200)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImHexApi::System::getInitArguments().insert({ "tip-of-the-day", tip.body });
|
ImHexApi::System::impl::addInitArgument("tip-of-the-day", tip.body);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace hex::init {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
ImHexApi::System::getInitArguments().insert({ "folder-creation-error", {} });
|
ImHexApi::System::impl::addInitArgument("folder-creation-error");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ namespace hex::init {
|
||||||
if (plugins.empty()) {
|
if (plugins.empty()) {
|
||||||
log::error("No plugins found!");
|
log::error("No plugins found!");
|
||||||
|
|
||||||
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
|
ImHexApi::System::impl::addInitArgument("no-plugins");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,17 +274,17 @@ namespace hex::init {
|
||||||
|
|
||||||
if (loadErrors == plugins.size()) {
|
if (loadErrors == plugins.size()) {
|
||||||
log::error("No plugins loaded successfully!");
|
log::error("No plugins loaded successfully!");
|
||||||
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
|
ImHexApi::System::impl::addInitArgument("no-plugins");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builtinPlugins == 0) {
|
if (builtinPlugins == 0) {
|
||||||
log::error("Built-in plugin not found!");
|
log::error("Built-in plugin not found!");
|
||||||
ImHexApi::System::getInitArguments().insert({ "no-builtin-plugin", {} });
|
ImHexApi::System::impl::addInitArgument("no-builtin-plugin");
|
||||||
return false;
|
return false;
|
||||||
} else if (builtinPlugins > 1) {
|
} else if (builtinPlugins > 1) {
|
||||||
log::error("Found more than one built-in plugin!");
|
log::error("Found more than one built-in plugin!");
|
||||||
ImHexApi::System::getInitArguments().insert({ "multiple-builtin-plugins", {} });
|
ImHexApi::System::impl::addInitArgument("multiple-builtin-plugins");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,20 +324,20 @@ namespace hex::init {
|
||||||
|
|
||||||
std::vector<Task> getInitTasks() {
|
std::vector<Task> getInitTasks() {
|
||||||
return {
|
return {
|
||||||
{"Checking for updates...", checkForUpdates },
|
{ "Checking for updates...", checkForUpdates, false },
|
||||||
{ "Downloading information...", downloadInformation},
|
{ "Downloading information...", downloadInformation, true },
|
||||||
{ "Creating directories...", createDirectories },
|
{ "Loading fonts...", loadFonts, true },
|
||||||
{ "Loading settings...", loadSettings },
|
{ "Creating directories...", createDirectories, false },
|
||||||
{ "Loading plugins...", loadPlugins },
|
{ "Loading settings...", loadSettings, false },
|
||||||
{ "Loading fonts...", loadFonts },
|
{ "Loading plugins...", loadPlugins, false },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Task> getExitTasks() {
|
std::vector<Task> getExitTasks() {
|
||||||
return {
|
return {
|
||||||
{"Saving settings...", storeSettings },
|
{ "Saving settings...", storeSettings, false },
|
||||||
{ "Cleaning up shared data...", deleteSharedData},
|
{ "Cleaning up shared data...", deleteSharedData, false },
|
||||||
{ "Unloading plugins...", unloadPlugins },
|
{ "Unloading plugins...", unloadPlugins, false },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ int main(int argc, char **argv, char **envp) {
|
||||||
|
|
||||||
init::WindowSplash splashWindow;
|
init::WindowSplash splashWindow;
|
||||||
|
|
||||||
for (const auto &[name, task] : init::getInitTasks())
|
for (const auto &[name, task, async] : init::getInitTasks())
|
||||||
splashWindow.addStartupTask(name, task);
|
splashWindow.addStartupTask(name, task, async);
|
||||||
|
|
||||||
if (!splashWindow.loop())
|
if (!splashWindow.loop())
|
||||||
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
||||||
|
@ -42,7 +42,7 @@ int main(int argc, char **argv, char **envp) {
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
for (const auto &[name, task] : init::getExitTasks())
|
for (const auto &[name, task, async] : init::getExitTasks())
|
||||||
task();
|
task();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue