refactor(detour_hook): don't use detour hook pointers, should speed up hooks ticking (skip a deref compared to before) (#1827)

This commit is contained in:
Quentin 2023-07-24 09:40:28 +02:00 committed by GitHub
parent 069d7041f8
commit cad5e803c1
4 changed files with 57 additions and 45 deletions

View File

@ -7,17 +7,32 @@
namespace big namespace big
{ {
detour_hook::detour_hook(std::string name, void* detour) : detour_hook::detour_hook()
m_name(std::move(name)),
m_detour(detour)
{ {
} }
detour_hook::detour_hook(std::string name, void* target, void* detour) : detour_hook::detour_hook(const std::string& name, void* detour)
m_name(std::move(name)),
m_target(target),
m_detour(detour)
{ {
set_instance(name, detour);
}
detour_hook::detour_hook(const std::string& name, void* target, void* detour)
{
set_instance(name, target, detour);
}
void big::detour_hook::set_instance(const std::string& name, void* detour)
{
m_name = name;
m_detour = detour;
}
void big::detour_hook::set_instance(const std::string& name, void* target, void* detour)
{
m_name = name;
m_target = target;
m_detour = detour;
create_hook(); create_hook();
} }

View File

@ -5,8 +5,9 @@ namespace big
class detour_hook class detour_hook
{ {
public: public:
explicit detour_hook(std::string name, void* detour); explicit detour_hook();
explicit detour_hook(std::string name, void* target, void* detour); explicit detour_hook(const std::string& name, void* detour);
explicit detour_hook(const std::string& name, void* target, void* detour);
~detour_hook() noexcept; ~detour_hook() noexcept;
detour_hook(detour_hook&& that) = delete; detour_hook(detour_hook&& that) = delete;
@ -14,6 +15,9 @@ namespace big
detour_hook(detour_hook const&) = delete; detour_hook(detour_hook const&) = delete;
detour_hook& operator=(detour_hook const&) = delete; detour_hook& operator=(detour_hook const&) = delete;
void set_instance(const std::string& name, void* detour);
void set_instance(const std::string& name, void* target, void* detour);
void set_target_and_create_hook(void* target); void set_target_and_create_hook(void* target);
void enable(); void enable();
@ -31,8 +35,8 @@ namespace big
void create_hook(); void create_hook();
std::string m_name; std::string m_name;
void* m_original{}; void* m_original;
void* m_target{}; void* m_target;
void* m_detour{}; void* m_detour;
}; };
} }

View File

@ -26,7 +26,7 @@ namespace big
// aka the ones that still don't have their m_target assigned // aka the ones that still don't have their m_target assigned
for (auto& detour_hook_helper : m_detour_hook_helpers) for (auto& detour_hook_helper : m_detour_hook_helpers)
{ {
detour_hook_helper->m_detour_hook->set_target_and_create_hook(detour_hook_helper->m_on_hooking_available()); detour_hook_helper.m_detour_hook->set_target_and_create_hook(detour_hook_helper.m_on_hooking_available());
} }
detour_hook_helper::add<hooks::run_script_threads>("SH", g_pointers->m_gta.m_run_script_threads); detour_hook_helper::add<hooks::run_script_threads>("SH", g_pointers->m_gta.m_run_script_threads);
@ -140,9 +140,9 @@ namespace big
m_swapchain_hook.enable(); m_swapchain_hook.enable();
m_og_wndproc = WNDPROC(SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, LONG_PTR(&hooks::wndproc))); m_og_wndproc = WNDPROC(SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, LONG_PTR(&hooks::wndproc)));
for (const auto& detour_hook_helper : m_detour_hook_helpers) for (auto& detour_hook_helper : m_detour_hook_helpers)
{ {
detour_hook_helper->m_detour_hook->enable(); detour_hook_helper.m_detour_hook->enable();
} }
MH_ApplyQueued(); MH_ApplyQueued();
@ -154,9 +154,9 @@ namespace big
{ {
m_enabled = false; m_enabled = false;
for (const auto& detour_hook_helper : m_detour_hook_helpers) for (auto& detour_hook_helper : m_detour_hook_helpers)
{ {
detour_hook_helper->m_detour_hook->disable(); detour_hook_helper.m_detour_hook->disable();
} }
SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc)); SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc));
@ -164,16 +164,11 @@ namespace big
MH_ApplyQueued(); MH_ApplyQueued();
for (const auto& detour_hook_helper : m_detour_hook_helpers)
{
delete detour_hook_helper;
}
m_detour_hook_helpers.clear(); m_detour_hook_helpers.clear();
} }
hooking::detour_hook_helper::~detour_hook_helper() hooking::detour_hook_helper::~detour_hook_helper()
{ {
delete m_detour_hook;
} }
void hooking::detour_hook_helper::enable_hook_if_hooking_is_already_running() void hooking::detour_hook_helper::enable_hook_if_hooking_is_already_running()

View File

@ -192,55 +192,53 @@ namespace big
ret_ptr_fn m_on_hooking_available = nullptr; ret_ptr_fn m_on_hooking_available = nullptr;
detour_hook* m_detour_hook = nullptr; detour_hook* m_detour_hook;
~detour_hook_helper();
void enable_hook_if_hooking_is_already_running(); void enable_hook_if_hooking_is_already_running();
template<auto detour_function> template<auto detour_function>
struct hook_to_detour_hook_helper struct hook_to_detour_hook_helper
{ {
static inline detour_hook* m_detour_hook; static inline detour_hook m_detour_hook;
}; };
template<auto detour_function>
static detour_hook_helper* add_internal(detour_hook* dh)
{
auto d = new detour_hook_helper();
d->m_detour_hook = dh;
m_detour_hook_helpers.push_back(d);
hook_to_detour_hook_helper<detour_function>::m_detour_hook = dh;
return d;
}
public: public:
template<auto detour_function> template<auto detour_function>
static void add(const std::string& name, void* target) static void add(const std::string& name, void* target)
{ {
auto d = add_internal<detour_function>(new detour_hook(name, target, detour_function)); hook_to_detour_hook_helper<detour_function>::m_detour_hook.set_instance(name, target, detour_function);
d->enable_hook_if_hooking_is_already_running(); detour_hook_helper d{};
d.m_detour_hook = &hook_to_detour_hook_helper<detour_function>::m_detour_hook;
d.enable_hook_if_hooking_is_already_running();
m_detour_hook_helpers.push_back(d);
} }
template<auto detour_function> template<auto detour_function>
static void* add_lazy(const std::string& name, detour_hook_helper::ret_ptr_fn on_hooking_available) static void* add_lazy(const std::string& name, detour_hook_helper::ret_ptr_fn on_hooking_available)
{ {
auto d = add_internal<detour_function>(new detour_hook(name, detour_function)); hook_to_detour_hook_helper<detour_function>::m_detour_hook.set_instance(name, detour_function);
d->m_on_hooking_available = on_hooking_available;
d->enable_hook_if_hooking_is_already_running(); detour_hook_helper d{};
d.m_detour_hook = &hook_to_detour_hook_helper<detour_function>::m_detour_hook;
d.m_on_hooking_available = on_hooking_available;
d.enable_hook_if_hooking_is_already_running();
m_detour_hook_helpers.push_back(d);
return nullptr; return nullptr;
} }
~detour_hook_helper();
}; };
template<auto detour_function> template<auto detour_function>
static auto get_original() static auto get_original()
{ {
return detour_hook_helper::hook_to_detour_hook_helper<detour_function>::m_detour_hook->get_original<decltype(detour_function)>(); return detour_hook_helper::hook_to_detour_hook_helper<detour_function>::m_detour_hook.get_original<decltype(detour_function)>();
} }
private: private:
@ -251,7 +249,7 @@ namespace big
WNDPROC m_og_wndproc = nullptr; WNDPROC m_og_wndproc = nullptr;
static inline std::vector<detour_hook_helper*> m_detour_hook_helpers; static inline std::vector<detour_hook_helper> m_detour_hook_helpers;
}; };
inline hooking* g_hooking{}; inline hooking* g_hooking{};