55
66#pragma once
77
8+ #include < algorithm>
89#include < chrono>
10+ #include < cstdint>
11+ #include < initializer_list>
12+ #include < mutex>
913#include < random>
14+ #include < utility>
15+ #include < vector>
1016
1117#include < include/reshade.hpp>
1218
19+ #include " ./cross_addon.hpp"
20+
1321namespace renodx ::utils::random {
1422
23+ [[deprecated("Use random::Use() instead")]]
1524static std::vector<float *> binds;
1625
1726namespace internal {
18- static std::vector<std::mt19937> generators;
1927
20- static constexpr const auto RANDOM_RANGE = static_cast <float >((std::mt19937::max)() - (std::mt19937::min)());
28+ using FloatRandomizer = std::pair<float *, std::mt19937>;
29+
30+ struct __declspec (uuid(" b9c38ad7-3b9a-4fa9-94a7-18e9214bc9a6" )) SharedData {
31+ std::mutex mutex;
32+ cross_addon::vector<FloatRandomizer> binds;
33+ };
34+
35+ static cross_addon::Shared<SharedData> shared;
36+
37+ static constexpr const auto RANDOM_RANGE = static_cast <double >((std::mt19937::max)()) - static_cast <double >((std::mt19937::min)()) + 1.0 ;
2138
2239static void OnPresent (
2340 reshade::api::command_queue* queue,
@@ -26,39 +43,84 @@ static void OnPresent(
2643 const reshade::api::rect* dest_rect,
2744 uint32_t dirty_rect_count,
2845 const reshade::api::rect* dirty_rects) {
29- auto binds_count = binds.size ();
30- auto generators_count = generators.size ();
31-
32- for (size_t i = 0 ; i < binds_count; ++i) {
33- if (generators_count <= i) {
34- std::mt19937 generator = std::mt19937 (std::chrono::system_clock::now ().time_since_epoch ().count () + i);
35- generators.push_back (generator);
36- ++generators_count;
37- }
38- *binds[i] = (generators[i]() + (std::mt19937::min)()) / RANDOM_RANGE ;
46+ auto * data = shared.data ;
47+ if (data == nullptr ) return ;
48+
49+ std::lock_guard lock (data->mutex );
50+ for (auto & [value, generator] : data->binds ) {
51+ if (value == nullptr ) continue ;
52+
53+ *value = static_cast <float >(
54+ (static_cast <double >(generator ()) - static_cast <double >((std::mt19937::min)())) / RANDOM_RANGE );
3955 }
40- if (generators_count > binds_count) {
41- generators.resize (binds_count);
56+ }
57+ } // namespace internal
58+
59+ static bool AddBinding (float * bind) {
60+ if (internal::shared.data == nullptr ) {
61+ binds.push_back (bind);
62+ } else {
63+ std::lock_guard lock (internal::shared.data ->mutex );
64+ auto & shared_binds = internal::shared.data ->binds ;
65+ if (std::ranges::any_of (shared_binds, [bind](const internal::FloatRandomizer& item) {
66+ return item.first == bind;
67+ })) {
68+ return false ;
69+ }
70+ const auto seed = static_cast <std::mt19937::result_type>(
71+ std::chrono::steady_clock::now ().time_since_epoch ().count () + shared_binds.size ());
72+ shared_binds.push_back ({bind, std::mt19937 (seed)});
4273 }
74+ return true ;
4375}
4476
45- static bool attached = false ;
46- } // namespace internal
77+ static bool RemoveBinding (float * bind) {
78+ if (internal::shared.data == nullptr ) {
79+ auto it = std::ranges::find (binds, bind);
80+ if (it != binds.end ()) {
81+ binds.erase (it);
82+ return true ;
83+ }
84+ } else {
85+ std::lock_guard lock (internal::shared.data ->mutex );
86+ auto & shared_binds = internal::shared.data ->binds ;
87+ auto it = std::ranges::find_if (shared_binds, [bind](const internal::FloatRandomizer& item) {
88+ return item.first == bind;
89+ });
90+ if (it != shared_binds.end ()) {
91+ shared_binds.erase (it);
92+ return true ;
93+ }
94+ }
95+ return false ;
96+ }
4797
48- static void Use (DWORD fdw_reason) {
98+ static void Use (DWORD fdw_reason, std::initializer_list< float *> binds = {} ) {
4999 switch (fdw_reason) {
50100 case DLL_PROCESS_ATTACH :
51- if (internal::attached) return ;
52- internal::attached = true ;
53- reshade::log::message (reshade::log::level::info, " utils::random attached." );
101+ if (internal::shared.RegisterModule ()) {
102+ // log started
103+ reshade::log::message (reshade::log::level::info, " utils::random attached..." );
104+ }
105+ for (auto * bind : binds) {
106+ AddBinding (bind);
107+ }
108+ for (auto * bind : random::binds) {
109+ AddBinding (bind);
110+ }
54111
55- reshade::register_event <reshade::addon_event::present>(internal::OnPresent);
112+ internal::shared. RegisterEvent <reshade::addon_event::present>(internal::OnPresent);
56113 break ;
57114
58115 case DLL_PROCESS_DETACH :
59- if (!internal::attached) return ;
60- internal::attached = false ;
61- reshade::unregister_event<reshade::addon_event::present>(internal::OnPresent);
116+ internal::shared.UnregisterEvent <reshade::addon_event::present>(internal::OnPresent);
117+ for (auto * bind : random::binds) {
118+ RemoveBinding (bind);
119+ }
120+ for (auto * bind : binds) {
121+ RemoveBinding (bind);
122+ }
123+ internal::shared.UnregisterModule ();
62124
63125 break ;
64126 }
0 commit comments