Fix threading issues

This commit is contained in:
momo5502 2022-06-16 12:12:36 +02:00
parent 65fddf188a
commit 8c5e696720
6 changed files with 102 additions and 32 deletions

View File

@ -870,6 +870,11 @@ namespace arxan
open_process_hook.clear(); open_process_hook.clear();
} }
int priority() override
{
return 9999;
}
private: private:
uint8_t window_text_buffer_[15]{}; uint8_t window_text_buffer_[15]{};
}; };

View File

@ -150,7 +150,7 @@ namespace scheduler
class component final : public component_interface class component final : public component_interface
{ {
public: public:
void post_unpack() override void pre_start() override
{ {
thread = utils::thread::create_named_thread("Async Scheduler", []() thread = utils::thread::create_named_thread("Async Scheduler", []()
{ {

View File

@ -1,5 +1,6 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "splash.hpp"
#include "resource.hpp" #include "resource.hpp"
#include <utils/nt.hpp> #include <utils/nt.hpp>
@ -35,33 +36,23 @@ namespace splash
: image_(load_splash_image()) : image_(load_splash_image())
{ {
enable_dpi_awareness(); enable_dpi_awareness();
this->show(); this->window_thread_ = std::thread([this]
{
this->draw();
});
} }
void pre_start() override ~component()
{ {
this->draw_frame(); if (this->window_thread_.joinable())
{
this->window_thread_.detach();
}
} }
void pre_destroy() override void pre_destroy() override
{ {
this->destroy(); this->destroy();
MSG msg;
while (this->window_ && IsWindow(this->window_))
{
if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
std::this_thread::sleep_for(1ms);
}
}
this->window_ = nullptr;
} }
void post_unpack() override void post_unpack() override
@ -69,28 +60,75 @@ namespace splash
this->destroy(); this->destroy();
} }
void hide() const
{
if (this->window_ && IsWindow(this->window_))
{
ShowWindow(this->window_, SW_HIDE);
UpdateWindow(this->window_);
}
}
private: private:
std::atomic_bool join_safe_{false};
HWND window_{}; HWND window_{};
HANDLE image_{}; HANDLE image_{};
std::thread window_thread_{};
void draw_frame() const void destroy()
{
MSG msg{};
while (this->window_ && PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
void destroy() const
{ {
if (this->window_ && IsWindow(this->window_)) if (this->window_ && IsWindow(this->window_))
{ {
ShowWindow(this->window_, SW_HIDE); ShowWindow(this->window_, SW_HIDE);
DestroyWindow(this->window_); DestroyWindow(this->window_);
this->window_ = nullptr;
if (this->window_thread_.joinable())
{
this->window_thread_.join();
}
this->window_ = nullptr;
}
}
void draw()
{
this->show();
while (this->draw_frame())
{
std::this_thread::sleep_for(1ms);
}
this->window_ = nullptr;
UnregisterClassA("Black Ops III Splash Screen", utils::nt::library{}); UnregisterClassA("Black Ops III Splash Screen", utils::nt::library{});
} }
bool draw_frame() const
{
if (!this->window_)
{
return false;
}
MSG msg{};
bool success = true;
while (PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
if (msg.message == WM_DESTROY && msg.hwnd == this->window_)
{
PostQuitMessage(0);
}
if (msg.message == WM_QUIT)
{
success = false;
}
}
return success;
} }
void show() void show()
@ -158,6 +196,15 @@ namespace splash
} }
} }
}; };
void hide()
{
auto* splash_component = component_loader::get<component>();
if (splash_component)
{
splash_component->hide();
}
}
} }
REGISTER_COMPONENT(splash::component) REGISTER_COMPONENT(splash::component)

View File

@ -0,0 +1,6 @@
#pragma once
namespace splash
{
void hide();
}

View File

@ -21,4 +21,9 @@ public:
{ {
return true; return true;
} }
virtual int priority()
{
return 0;
}
}; };

View File

@ -5,7 +5,14 @@
void component_loader::register_component(std::unique_ptr<component_interface>&& component_) void component_loader::register_component(std::unique_ptr<component_interface>&& component_)
{ {
get_components().push_back(std::move(component_)); auto& components = get_components();
components.push_back(std::move(component_));
std::ranges::stable_sort(components, [](const std::unique_ptr<component_interface>& a,
const std::unique_ptr<component_interface>& b)
{
return a->priority() > b->priority();
});
} }
bool component_loader::pre_start() bool component_loader::pre_start()