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 setPortableVersion(bool enabled);
|
||||
|
||||
void addInitArgument(const std::string &key, const std::string &value = { });
|
||||
}
|
||||
|
||||
struct ProgramArguments {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <hex.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/color.h>
|
||||
|
@ -30,6 +31,9 @@ namespace hex::log {
|
|||
|
||||
template<typename... T>
|
||||
[[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();
|
||||
|
||||
printPrefix(dest, ts, level);
|
||||
|
|
|
@ -385,6 +385,13 @@ namespace hex {
|
|||
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();
|
||||
|
||||
void addStartupTask(const std::string &taskName, const TaskFunction &task) {
|
||||
this->m_tasks.emplace_back(taskName, task);
|
||||
void addStartupTask(const std::string &taskName, const TaskFunction &task, bool async) {
|
||||
this->m_tasks.emplace_back(taskName, task, async);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -37,7 +37,7 @@ namespace hex::init {
|
|||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace hex::init {
|
|||
struct Task {
|
||||
std::string name;
|
||||
std::function<bool()> function;
|
||||
bool async;
|
||||
};
|
||||
|
||||
std::vector<Task> getInitTasks();
|
||||
|
|
|
@ -43,15 +43,27 @@ namespace hex::init {
|
|||
return std::async(std::launch::async, [this] {
|
||||
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);
|
||||
this->m_currTaskName = name;
|
||||
}
|
||||
|
||||
try {
|
||||
auto runTask = [&, task = task] {
|
||||
if (!task())
|
||||
status = false;
|
||||
|
||||
tasksCompleted++;
|
||||
};
|
||||
|
||||
try {
|
||||
if (async) {
|
||||
std::thread(runTask).detach();
|
||||
} else {
|
||||
runTask();
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
log::error("Init task '{}' threw an exception: {}", name, e.what());
|
||||
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
|
||||
std::this_thread::sleep_for(200ms);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace hex::init {
|
|||
auto latestVersion = releases.body["tag_name"].get<std::string_view>();
|
||||
|
||||
if (latestVersion != currVersion)
|
||||
ImHexApi::System::getInitArguments().insert({ "update-available", latestVersion.data() });
|
||||
ImHexApi::System::impl::addInitArgument("update-available", latestVersion.data());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ namespace hex::init {
|
|||
if (tip.code != 200)
|
||||
return false;
|
||||
|
||||
ImHexApi::System::getInitArguments().insert({ "tip-of-the-day", tip.body });
|
||||
ImHexApi::System::impl::addInitArgument("tip-of-the-day", tip.body);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ namespace hex::init {
|
|||
}
|
||||
|
||||
if (!result)
|
||||
ImHexApi::System::getInitArguments().insert({ "folder-creation-error", {} });
|
||||
ImHexApi::System::impl::addInitArgument("folder-creation-error");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ namespace hex::init {
|
|||
if (plugins.empty()) {
|
||||
log::error("No plugins found!");
|
||||
|
||||
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
|
||||
ImHexApi::System::impl::addInitArgument("no-plugins");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -274,17 +274,17 @@ namespace hex::init {
|
|||
|
||||
if (loadErrors == plugins.size()) {
|
||||
log::error("No plugins loaded successfully!");
|
||||
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
|
||||
ImHexApi::System::impl::addInitArgument("no-plugins");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (builtinPlugins == 0) {
|
||||
log::error("Built-in plugin not found!");
|
||||
ImHexApi::System::getInitArguments().insert({ "no-builtin-plugin", {} });
|
||||
ImHexApi::System::impl::addInitArgument("no-builtin-plugin");
|
||||
return false;
|
||||
} else if (builtinPlugins > 1) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -324,20 +324,20 @@ namespace hex::init {
|
|||
|
||||
std::vector<Task> getInitTasks() {
|
||||
return {
|
||||
{"Checking for updates...", checkForUpdates },
|
||||
{ "Downloading information...", downloadInformation},
|
||||
{ "Creating directories...", createDirectories },
|
||||
{ "Loading settings...", loadSettings },
|
||||
{ "Loading plugins...", loadPlugins },
|
||||
{ "Loading fonts...", loadFonts },
|
||||
{ "Checking for updates...", checkForUpdates, false },
|
||||
{ "Downloading information...", downloadInformation, true },
|
||||
{ "Loading fonts...", loadFonts, true },
|
||||
{ "Creating directories...", createDirectories, false },
|
||||
{ "Loading settings...", loadSettings, false },
|
||||
{ "Loading plugins...", loadPlugins, false },
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<Task> getExitTasks() {
|
||||
return {
|
||||
{"Saving settings...", storeSettings },
|
||||
{ "Cleaning up shared data...", deleteSharedData},
|
||||
{ "Unloading plugins...", unloadPlugins },
|
||||
{ "Saving settings...", storeSettings, false },
|
||||
{ "Cleaning up shared data...", deleteSharedData, false },
|
||||
{ "Unloading plugins...", unloadPlugins, false },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@ int main(int argc, char **argv, char **envp) {
|
|||
|
||||
init::WindowSplash splashWindow;
|
||||
|
||||
for (const auto &[name, task] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task);
|
||||
for (const auto &[name, task, async] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task, async);
|
||||
|
||||
if (!splashWindow.loop())
|
||||
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
||||
|
@ -42,7 +42,7 @@ int main(int argc, char **argv, char **envp) {
|
|||
|
||||
// Clean up
|
||||
ON_SCOPE_EXIT {
|
||||
for (const auto &[name, task] : init::getExitTasks())
|
||||
for (const auto &[name, task, async] : init::getExitTasks())
|
||||
task();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue