mirror of
https://github.com/orange-cpp/omath.git
synced 2026-05-06 20:43:27 +00:00
removed copying
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#ifdef OMATH_ENABLE_HOOKING
|
#ifdef OMATH_ENABLE_HOOKING
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
@@ -43,6 +44,9 @@ namespace omath::hooks
|
|||||||
// Return nullopt to pass the message to the original WndProc; return a value to intercept it.
|
// Return nullopt to pass the message to the original WndProc; return a value to intercept it.
|
||||||
using wnd_proc_callback = std::function<std::optional<LRESULT>(HWND, UINT, WPARAM, LPARAM)>;
|
using wnd_proc_callback = std::function<std::optional<LRESULT>(HWND, UINT, WPARAM, LPARAM)>;
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
using callback_ptr = std::shared_ptr<const Callback>;
|
||||||
|
|
||||||
[[nodiscard]] static HooksManager& get();
|
[[nodiscard]] static HooksManager& get();
|
||||||
HooksManager(const HooksManager&) = delete;
|
HooksManager(const HooksManager&) = delete;
|
||||||
HooksManager& operator=(const HooksManager&) = delete;
|
HooksManager& operator=(const HooksManager&) = delete;
|
||||||
@@ -142,15 +146,15 @@ namespace omath::hooks
|
|||||||
safetyhook::InlineHook m_opengl_wgl_swap_buffers_hook;
|
safetyhook::InlineHook m_opengl_wgl_swap_buffers_hook;
|
||||||
safetyhook::InlineHook m_opengl_swap_buffers_hook;
|
safetyhook::InlineHook m_opengl_swap_buffers_hook;
|
||||||
|
|
||||||
dx9_present_callback m_dx9_present_cb;
|
callback_ptr<dx9_present_callback> m_dx9_present_cb;
|
||||||
dx9_reset_callback m_dx9_reset_cb;
|
callback_ptr<dx9_reset_callback> m_dx9_reset_cb;
|
||||||
dx9_end_scene_callback m_dx9_end_scene_cb;
|
callback_ptr<dx9_end_scene_callback> m_dx9_end_scene_cb;
|
||||||
|
|
||||||
present_callback m_present_cb;
|
callback_ptr<present_callback> m_present_cb;
|
||||||
resize_buffers_callback m_resize_buffers_cb;
|
callback_ptr<resize_buffers_callback> m_resize_buffers_cb;
|
||||||
execute_command_lists_callback m_execute_command_lists_cb;
|
callback_ptr<execute_command_lists_callback> m_execute_command_lists_cb;
|
||||||
opengl_swap_buffers_callback m_opengl_swap_buffers_cb;
|
callback_ptr<opengl_swap_buffers_callback> m_opengl_swap_buffers_cb;
|
||||||
wnd_proc_callback m_wnd_proc_cb;
|
callback_ptr<wnd_proc_callback> m_wnd_proc_cb;
|
||||||
};
|
};
|
||||||
} // namespace omath::hooks
|
} // namespace omath::hooks
|
||||||
|
|
||||||
|
|||||||
@@ -259,19 +259,19 @@ namespace omath::hooks
|
|||||||
void HooksManager::set_on_dx9_present(dx9_present_callback callback)
|
void HooksManager::set_on_dx9_present(dx9_present_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_dx9_present_mutex);
|
std::unique_lock lock(m_dx9_present_mutex);
|
||||||
m_dx9_present_cb = std::move(callback);
|
m_dx9_present_cb = callback ? std::make_shared<dx9_present_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HooksManager::set_on_dx9_reset(dx9_reset_callback callback)
|
void HooksManager::set_on_dx9_reset(dx9_reset_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_dx9_reset_mutex);
|
std::unique_lock lock(m_dx9_reset_mutex);
|
||||||
m_dx9_reset_cb = std::move(callback);
|
m_dx9_reset_cb = callback ? std::make_shared<dx9_reset_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HooksManager::set_on_dx9_end_scene(dx9_end_scene_callback callback)
|
void HooksManager::set_on_dx9_end_scene(dx9_end_scene_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_dx9_end_scene_mutex);
|
std::unique_lock lock(m_dx9_end_scene_mutex);
|
||||||
m_dx9_end_scene_cb = std::move(callback);
|
m_dx9_end_scene_cb = callback ? std::make_shared<dx9_end_scene_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HooksManager::hook_dx11()
|
bool HooksManager::hook_dx11()
|
||||||
@@ -433,25 +433,27 @@ namespace omath::hooks
|
|||||||
void HooksManager::set_on_opengl_swap_buffers(opengl_swap_buffers_callback callback)
|
void HooksManager::set_on_opengl_swap_buffers(opengl_swap_buffers_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_opengl_swap_buffers_mutex);
|
std::unique_lock lock(m_opengl_swap_buffers_mutex);
|
||||||
m_opengl_swap_buffers_cb = std::move(callback);
|
m_opengl_swap_buffers_cb =
|
||||||
|
callback ? std::make_shared<opengl_swap_buffers_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HooksManager::set_on_present(present_callback callback)
|
void HooksManager::set_on_present(present_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_present_mutex);
|
std::unique_lock lock(m_present_mutex);
|
||||||
m_present_cb = std::move(callback);
|
m_present_cb = callback ? std::make_shared<present_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HooksManager::set_on_resize_buffers(resize_buffers_callback callback)
|
void HooksManager::set_on_resize_buffers(resize_buffers_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_resize_buffers_mutex);
|
std::unique_lock lock(m_resize_buffers_mutex);
|
||||||
m_resize_buffers_cb = std::move(callback);
|
m_resize_buffers_cb = callback ? std::make_shared<resize_buffers_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HooksManager::set_on_execute_command_lists(execute_command_lists_callback callback)
|
void HooksManager::set_on_execute_command_lists(execute_command_lists_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_execute_command_lists_mutex);
|
std::unique_lock lock(m_execute_command_lists_mutex);
|
||||||
m_execute_command_lists_cb = std::move(callback);
|
m_execute_command_lists_cb =
|
||||||
|
callback ? std::make_shared<execute_command_lists_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HooksManager::hook_wnd_proc(HWND hwnd)
|
bool HooksManager::hook_wnd_proc(HWND hwnd)
|
||||||
@@ -486,24 +488,25 @@ namespace omath::hooks
|
|||||||
void HooksManager::set_on_wnd_proc(wnd_proc_callback callback)
|
void HooksManager::set_on_wnd_proc(wnd_proc_callback callback)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_wnd_proc_mutex);
|
std::unique_lock lock(m_wnd_proc_mutex);
|
||||||
m_wnd_proc_cb = std::move(callback);
|
m_wnd_proc_cb = callback ? std::make_shared<wnd_proc_callback>(std::move(callback)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detour implementations: copy callback under shared lock, call it unlocked,
|
// Detour implementations: copy a shared_ptr to the callback under shared lock, call it unlocked,
|
||||||
// then call original. This avoids a deadlock if the callback itself calls set_on_*().
|
// then call original. This avoids copying captured lambda state every frame and still avoids
|
||||||
|
// a deadlock if the callback itself calls set_on_*().
|
||||||
|
|
||||||
HRESULT __stdcall HooksManager::dx9_present_detour(IDirect3DDevice9* p_device, const RECT* p_source_rect,
|
HRESULT __stdcall HooksManager::dx9_present_detour(IDirect3DDevice9* p_device, const RECT* p_source_rect,
|
||||||
const RECT* p_dest_rect, HWND h_dest_window_override,
|
const RECT* p_dest_rect, HWND h_dest_window_override,
|
||||||
const RGNDATA* p_dirty_region)
|
const RGNDATA* p_dirty_region)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
dx9_present_callback cb;
|
callback_ptr<dx9_present_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_dx9_present_mutex);
|
std::shared_lock lock(mgr.m_dx9_present_mutex);
|
||||||
cb = mgr.m_dx9_present_cb;
|
cb = mgr.m_dx9_present_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_device, p_source_rect, p_dest_rect, h_dest_window_override, p_dirty_region);
|
(*cb)(p_device, p_source_rect, p_dest_rect, h_dest_window_override, p_dirty_region);
|
||||||
return mgr.m_dx9_present_hook.call<HRESULT>(p_device, p_source_rect, p_dest_rect, h_dest_window_override,
|
return mgr.m_dx9_present_hook.call<HRESULT>(p_device, p_source_rect, p_dest_rect, h_dest_window_override,
|
||||||
p_dirty_region);
|
p_dirty_region);
|
||||||
}
|
}
|
||||||
@@ -512,39 +515,39 @@ namespace omath::hooks
|
|||||||
D3DPRESENT_PARAMETERS* p_presentation_parameters)
|
D3DPRESENT_PARAMETERS* p_presentation_parameters)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
dx9_reset_callback cb;
|
callback_ptr<dx9_reset_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_dx9_reset_mutex);
|
std::shared_lock lock(mgr.m_dx9_reset_mutex);
|
||||||
cb = mgr.m_dx9_reset_cb;
|
cb = mgr.m_dx9_reset_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_device, p_presentation_parameters);
|
(*cb)(p_device, p_presentation_parameters);
|
||||||
return mgr.m_dx9_reset_hook.call<HRESULT>(p_device, p_presentation_parameters);
|
return mgr.m_dx9_reset_hook.call<HRESULT>(p_device, p_presentation_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall HooksManager::dx9_end_scene_detour(IDirect3DDevice9* p_device)
|
HRESULT __stdcall HooksManager::dx9_end_scene_detour(IDirect3DDevice9* p_device)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
dx9_end_scene_callback cb;
|
callback_ptr<dx9_end_scene_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_dx9_end_scene_mutex);
|
std::shared_lock lock(mgr.m_dx9_end_scene_mutex);
|
||||||
cb = mgr.m_dx9_end_scene_cb;
|
cb = mgr.m_dx9_end_scene_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_device);
|
(*cb)(p_device);
|
||||||
return mgr.m_dx9_end_scene_hook.call<HRESULT>(p_device);
|
return mgr.m_dx9_end_scene_hook.call<HRESULT>(p_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall HooksManager::dx11_present_detour(IDXGISwapChain* p_swap_chain, UINT sync_interval, UINT flags)
|
HRESULT __stdcall HooksManager::dx11_present_detour(IDXGISwapChain* p_swap_chain, UINT sync_interval, UINT flags)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
present_callback cb;
|
callback_ptr<present_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_present_mutex);
|
std::shared_lock lock(mgr.m_present_mutex);
|
||||||
cb = mgr.m_present_cb;
|
cb = mgr.m_present_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_swap_chain, sync_interval, flags);
|
(*cb)(p_swap_chain, sync_interval, flags);
|
||||||
return mgr.m_dx11_present_hook.call<HRESULT>(p_swap_chain, sync_interval, flags);
|
return mgr.m_dx11_present_hook.call<HRESULT>(p_swap_chain, sync_interval, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,13 +556,13 @@ namespace omath::hooks
|
|||||||
UINT swap_chain_flags)
|
UINT swap_chain_flags)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
resize_buffers_callback cb;
|
callback_ptr<resize_buffers_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_resize_buffers_mutex);
|
std::shared_lock lock(mgr.m_resize_buffers_mutex);
|
||||||
cb = mgr.m_resize_buffers_cb;
|
cb = mgr.m_resize_buffers_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
|
(*cb)(p_swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
|
||||||
return mgr.m_dx11_resize_buffers_hook.call<HRESULT>(p_swap_chain, buffer_count, width, height, new_format,
|
return mgr.m_dx11_resize_buffers_hook.call<HRESULT>(p_swap_chain, buffer_count, width, height, new_format,
|
||||||
swap_chain_flags);
|
swap_chain_flags);
|
||||||
}
|
}
|
||||||
@@ -567,13 +570,13 @@ namespace omath::hooks
|
|||||||
HRESULT __stdcall HooksManager::dx12_present_detour(IDXGISwapChain* p_swap_chain, UINT sync_interval, UINT flags)
|
HRESULT __stdcall HooksManager::dx12_present_detour(IDXGISwapChain* p_swap_chain, UINT sync_interval, UINT flags)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
present_callback cb;
|
callback_ptr<present_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_present_mutex);
|
std::shared_lock lock(mgr.m_present_mutex);
|
||||||
cb = mgr.m_present_cb;
|
cb = mgr.m_present_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_swap_chain, sync_interval, flags);
|
(*cb)(p_swap_chain, sync_interval, flags);
|
||||||
return mgr.m_dx12_present_hook.call<HRESULT>(p_swap_chain, sync_interval, flags);
|
return mgr.m_dx12_present_hook.call<HRESULT>(p_swap_chain, sync_interval, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,13 +585,13 @@ namespace omath::hooks
|
|||||||
UINT swap_chain_flags)
|
UINT swap_chain_flags)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
resize_buffers_callback cb;
|
callback_ptr<resize_buffers_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_resize_buffers_mutex);
|
std::shared_lock lock(mgr.m_resize_buffers_mutex);
|
||||||
cb = mgr.m_resize_buffers_cb;
|
cb = mgr.m_resize_buffers_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
|
(*cb)(p_swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
|
||||||
return mgr.m_dx12_resize_buffers_hook.call<HRESULT>(p_swap_chain, buffer_count, width, height, new_format,
|
return mgr.m_dx12_resize_buffers_hook.call<HRESULT>(p_swap_chain, buffer_count, width, height, new_format,
|
||||||
swap_chain_flags);
|
swap_chain_flags);
|
||||||
}
|
}
|
||||||
@@ -598,13 +601,13 @@ namespace omath::hooks
|
|||||||
ID3D12CommandList* const* pp_command_lists)
|
ID3D12CommandList* const* pp_command_lists)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
execute_command_lists_callback cb;
|
callback_ptr<execute_command_lists_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_execute_command_lists_mutex);
|
std::shared_lock lock(mgr.m_execute_command_lists_mutex);
|
||||||
cb = mgr.m_execute_command_lists_cb;
|
cb = mgr.m_execute_command_lists_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(p_command_queue, num_command_lists, pp_command_lists);
|
(*cb)(p_command_queue, num_command_lists, pp_command_lists);
|
||||||
mgr.m_dx12_execute_command_lists_hook.call<void>(p_command_queue, num_command_lists, pp_command_lists);
|
mgr.m_dx12_execute_command_lists_hook.call<void>(p_command_queue, num_command_lists, pp_command_lists);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,13 +619,13 @@ namespace omath::hooks
|
|||||||
{
|
{
|
||||||
g_is_inside_opengl_swap_buffers = true;
|
g_is_inside_opengl_swap_buffers = true;
|
||||||
|
|
||||||
opengl_swap_buffers_callback cb;
|
callback_ptr<opengl_swap_buffers_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_opengl_swap_buffers_mutex);
|
std::shared_lock lock(mgr.m_opengl_swap_buffers_mutex);
|
||||||
cb = mgr.m_opengl_swap_buffers_cb;
|
cb = mgr.m_opengl_swap_buffers_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(hdc);
|
(*cb)(hdc);
|
||||||
|
|
||||||
const BOOL result = mgr.m_opengl_wgl_swap_buffers_hook.call<BOOL>(hdc);
|
const BOOL result = mgr.m_opengl_wgl_swap_buffers_hook.call<BOOL>(hdc);
|
||||||
g_is_inside_opengl_swap_buffers = false;
|
g_is_inside_opengl_swap_buffers = false;
|
||||||
@@ -640,13 +643,13 @@ namespace omath::hooks
|
|||||||
{
|
{
|
||||||
g_is_inside_opengl_swap_buffers = true;
|
g_is_inside_opengl_swap_buffers = true;
|
||||||
|
|
||||||
opengl_swap_buffers_callback cb;
|
callback_ptr<opengl_swap_buffers_callback> cb;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_opengl_swap_buffers_mutex);
|
std::shared_lock lock(mgr.m_opengl_swap_buffers_mutex);
|
||||||
cb = mgr.m_opengl_swap_buffers_cb;
|
cb = mgr.m_opengl_swap_buffers_cb;
|
||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
cb(hdc);
|
(*cb)(hdc);
|
||||||
|
|
||||||
const BOOL result = mgr.m_opengl_swap_buffers_hook.call<BOOL>(hdc);
|
const BOOL result = mgr.m_opengl_swap_buffers_hook.call<BOOL>(hdc);
|
||||||
g_is_inside_opengl_swap_buffers = false;
|
g_is_inside_opengl_swap_buffers = false;
|
||||||
@@ -659,7 +662,7 @@ namespace omath::hooks
|
|||||||
LRESULT __stdcall HooksManager::wnd_proc_detour(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
LRESULT __stdcall HooksManager::wnd_proc_detour(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||||||
{
|
{
|
||||||
auto& mgr = get();
|
auto& mgr = get();
|
||||||
wnd_proc_callback cb;
|
callback_ptr<wnd_proc_callback> cb;
|
||||||
WNDPROC original;
|
WNDPROC original;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(mgr.m_wnd_proc_mutex);
|
std::shared_lock lock(mgr.m_wnd_proc_mutex);
|
||||||
@@ -668,7 +671,7 @@ namespace omath::hooks
|
|||||||
}
|
}
|
||||||
if (cb)
|
if (cb)
|
||||||
{
|
{
|
||||||
if (const auto result = cb(hwnd, msg, w_param, l_param))
|
if (const auto result = (*cb)(hwnd, msg, w_param, l_param))
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
return CallWindowProc(original, hwnd, msg, w_param, l_param);
|
return CallWindowProc(original, hwnd, msg, w_param, l_param);
|
||||||
|
|||||||
Reference in New Issue
Block a user