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();
}
int priority() override
{
return 9999;
}
private:
uint8_t window_text_buffer_[15]{};
};

View File

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

View File

@ -1,5 +1,6 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "splash.hpp"
#include "resource.hpp"
#include <utils/nt.hpp>
@ -35,33 +36,23 @@ namespace splash
: image_(load_splash_image())
{
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
{
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
@ -69,30 +60,77 @@ namespace splash
this->destroy();
}
private:
HWND window_{};
HANDLE image_{};
void draw_frame() const
void hide() const
{
MSG msg{};
while (this->window_ && PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
if (this->window_ && IsWindow(this->window_))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
ShowWindow(this->window_, SW_HIDE);
UpdateWindow(this->window_);
}
}
void destroy() const
private:
std::atomic_bool join_safe_{false};
HWND window_{};
HANDLE image_{};
std::thread window_thread_{};
void destroy()
{
if (this->window_ && IsWindow(this->window_))
{
ShowWindow(this->window_, SW_HIDE);
DestroyWindow(this->window_);
UnregisterClassA("Black Ops III Splash Screen", utils::nt::library{});
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{});
}
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()
{
WNDCLASSA wnd_class;
@ -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)

View File

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

View File

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

View File

@ -5,7 +5,14 @@
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()