@@ -27,9 +27,6 @@ public:
27
27
int MergeUpdate (); // called from uMod_IDirect3DDevice9::BeginScene()
28
28
void Initialize ();
29
29
30
- // Add TextureFileStruct data, return size of data added. 0 on failure.
31
- unsigned long AddFile (TexEntry& entry, bool compress = false );
32
-
33
30
std::vector<uMod_IDirect3DTexture9*> OriginalTextures;
34
31
// stores the pointer to the uMod_IDirect3DTexture9 objects created by the game
35
32
std::vector<uMod_IDirect3DVolumeTexture9*> OriginalVolumeTextures;
@@ -53,9 +50,8 @@ private:
53
50
int LockMutex ();
54
51
int UnlockMutex ();
55
52
HANDLE hMutex;
56
- std::mutex mutex;
57
53
58
- std::unordered_map<HashType, TextureFileStruct*> modded_textures;
54
+ std::unordered_map<HashType, gsl::owner< TextureFileStruct*> > modded_textures;
59
55
// array which stores the file in memory and the hash of each texture to be modded
60
56
61
57
// called if a target texture is found
@@ -83,8 +79,8 @@ TextureClient::~TextureClient()
83
79
if (hMutex != nullptr ) {
84
80
CloseHandle (hMutex);
85
81
}
86
- for (const auto & it : modded_textures) {
87
- delete it. second ;
82
+ for (const auto texture_file_struct : modded_textures | std::views::values ) {
83
+ delete texture_file_struct ;
88
84
}
89
85
modded_textures.clear ();
90
86
}
@@ -159,47 +155,44 @@ int TextureClient::UnlockMutex()
159
155
return RETURN_OK;
160
156
}
161
157
162
- unsigned long TextureClient:: AddFile (TexEntry& entry, const bool compress)
158
+ gsl::owner<TextureFileStruct*> AddFile (TexEntry& entry, const bool compress, const std::filesystem::path& dll_path )
163
159
{
164
- if (modded_textures.contains (entry.crc_hash )) {
165
- return 0 ;
166
- }
167
- auto texture_file_struct = new TextureFileStruct ();
160
+ const auto texture_file_struct = new TextureFileStruct ();
168
161
texture_file_struct->crc_hash = entry.crc_hash ;
169
- should_update = true ;
170
162
const auto dds_blob = TextureFunction::ConvertToCompressedDDS (entry, compress, dll_path);
171
163
texture_file_struct->data .assign (static_cast <BYTE*>(dds_blob.GetBufferPointer ()), static_cast <BYTE*>(dds_blob.GetBufferPointer ()) + dds_blob.GetBufferSize ());
172
- std::lock_guard lock (mutex);
173
- modded_textures.emplace (entry.crc_hash , texture_file_struct);
174
- return texture_file_struct->data .size ();
164
+ return texture_file_struct;
175
165
}
176
166
177
- unsigned ProcessModfile (TextureClient& client , const std::string& modfile , const bool compress)
167
+ std::vector<gsl::owner<TextureFileStruct*>> ProcessModfile (const std::string& modfile , const std::filesystem::path& dll_path , const bool compress)
178
168
{
179
169
const auto hr = CoInitializeEx (nullptr , COINIT_APARTMENTTHREADED);
180
- if (FAILED (hr)) return 0 ;
170
+ if (FAILED (hr)) return {} ;
181
171
Message (" Initialize: loading file %s... " , modfile.c_str ());
182
172
auto file_loader = ModfileLoader (modfile);
183
173
auto entries = file_loader.GetContents ();
184
174
if (entries.empty ()) {
185
175
Message (" No entries found.\n " );
186
- return 0 ;
176
+ return {} ;
187
177
}
188
178
Message (" %zu textures... " , entries.size ());
189
- unsigned long file_bytes_loaded = 0 ;
179
+ std::vector<gsl::owner<TextureFileStruct*>> texture_file_structs;
180
+ texture_file_structs.reserve (entries.size ());
181
+ unsigned file_bytes_loaded = 0 ;
190
182
for (auto & tpf_entry : entries) {
191
- file_bytes_loaded += client.AddFile (tpf_entry, compress);
183
+ const auto tex_file_struct = AddFile (tpf_entry, compress, dll_path);
184
+ texture_file_structs.push_back (tex_file_struct);
185
+ file_bytes_loaded += texture_file_structs.back ()->data .size ();
192
186
}
193
187
entries.clear ();
194
188
Message (" %d bytes loaded.\n " , file_bytes_loaded);
195
189
CoUninitialize ();
196
- return file_bytes_loaded ;
190
+ return texture_file_structs ;
197
191
}
198
192
199
193
void TextureClient::LoadModsFromFile (const char * source)
200
194
{
201
195
static std::vector<std::string> loaded_modfiles{};
202
- static unsigned long loaded_size = 0 ;
203
196
Message (" Initialize: searching in %s\n " , source);
204
197
205
198
std::ifstream file (source);
@@ -226,20 +219,32 @@ void TextureClient::LoadModsFromFile(const char* source)
226
219
files_size += std::filesystem::file_size (modfile);
227
220
}
228
221
}
229
- std::vector<std::future<unsigned >> futures;
222
+ std::vector<std::future<std::vector<gsl::owner<TextureFileStruct*>> >> futures;
230
223
for (const auto modfile : modfiles) {
231
- futures.emplace_back (std::async (std::launch::async, ProcessModfile, std::ref (* this ), modfile , files_size > 400'000'000 ));
224
+ futures.emplace_back (std::async (std::launch::async, ProcessModfile, modfile, dll_path , files_size > 400'000'000 ));
232
225
}
233
- // Join all threads
226
+ auto loaded_size = 0u ;
234
227
for (auto & future : futures) {
235
- loaded_size += future.get ();
228
+ const auto texture_file_structs = future.get ();
229
+ for (const auto texture_file_struct : texture_file_structs) {
230
+ if (!texture_file_struct->crc_hash ) continue ;
231
+ if (!modded_textures.contains (texture_file_struct->crc_hash )) {
232
+ modded_textures.emplace (texture_file_struct->crc_hash , texture_file_struct);
233
+ loaded_size += texture_file_struct->data .size ();
234
+ }
235
+ else {
236
+ delete texture_file_struct;
237
+ }
238
+ }
239
+ should_update = true ;
236
240
}
237
241
Message (" Finished loading mods from %s: Loaded %u bytes (%u mb)" , source, loaded_size, loaded_size / 1024 / 1024 );
238
242
}
239
243
240
244
void TextureClient::Initialize ()
241
245
{
242
- Message (" Initialize: begin\n " );
246
+ const auto t1 = std::chrono::high_resolution_clock::now ();
247
+ Info (" Initialize: begin\n " );
243
248
Message (" Initialize: searching for modlist.txt\n " );
244
249
char gwpath[MAX_PATH]{};
245
250
GetModuleFileName (GetModuleHandle (nullptr ), gwpath, MAX_PATH); // ask for name and path of this executable
@@ -254,8 +259,9 @@ void TextureClient::Initialize()
254
259
LoadModsFromFile (modlist.string ().c_str ());
255
260
}
256
261
}
257
-
258
- Message (" Initialize: end\n " );
262
+ const auto t2 = std::chrono::high_resolution_clock::now ();
263
+ const auto ms = duration_cast<std::chrono::milliseconds>(t2 - t1);
264
+ Info (" Initialize: end, took %d ms\n " , ms);
259
265
}
260
266
261
267
int TextureClient::AddTexture (uModTexturePtr auto pTexture)
0 commit comments