ArcdpsExtension
 
Loading...
Searching...
No Matches
IconLoader.h
Go to the documentation of this file.
1#pragma once
2
3#include "Singleton.h"
4
5#include <condition_variable>
6#include <cstdint>
7#include <filesystem>
8#include <mutex>
9#include <queue>
10#include <stop_token>
11#include <string>
12#include <thread>
13#include <unordered_map>
14#include <utility>
15#include <variant>
16#include <vector>
17
18// Windows
19#include <atlbase.h>
20#include <d3d11.h>
21#include <dxgiformat.h>
22#include <wincodec.h>
23#include <windows.h>
24
25namespace ArcdpsExtension {
26 template<typename From, typename To>
27 concept static_castable = requires(From f) {
28 static_cast<To>(f);
29 };
30
31 using IconLoaderKeyType = uint64_t;
32
33 template<typename T>
35
60 class IconLoader final : public Singleton<IconLoader> {
61 public:
68 IconLoader(HMODULE pDll, ID3D11Device* pD11Device);
69 ~IconLoader() override;
70
76 void RegisterFile(IconLoaderKey auto pName, const std::filesystem::path& pFilepath);
77
83 void RegisterUrl(IconLoaderKey auto pName, const std::string& pUrl);
84
90 void RegisterGw2Dat(IconLoaderKey auto pName, const std::string& pId);
91
97 void RegisterResource(IconLoaderKey auto pName, UINT pId);
98
104 ID3D11ShaderResourceView* Draw(IconLoaderKey auto pName);
105
106 private:
107 struct Icon {
108 UINT Width;
109 UINT Height;
110 ID3D11ShaderResourceView* Texture;
111
112 Icon(UINT pWidth, UINT pHeight, ID3D11ShaderResourceView* pTexture) : Width(pWidth), Height(pHeight), Texture(pTexture) {}
113 };
114
115 enum class LoadWay {
116 File,
117 Url,
118 Gw2Dat,
119 Resource,
120 };
121 class QueueIcon {
122 public:
123 QueueIcon(IconLoaderKeyType pName, IconLoader& pIconLoader, LoadWay pWay, const auto& pResource) : mIconLoader(pIconLoader), mName(pName), mWay(pWay), mResource(pResource) {}
124
125 protected:
126 IconLoaderKeyType mName;
127 LoadWay mWay;
128 std::variant<std::filesystem::path, std::string, UINT> mResource;
129 IconLoader& mIconLoader;
130 UINT mWidth = 0;
131 UINT mHeight = 0;
132 std::vector<uint8_t> mPixelBuffer;
133 DXGI_FORMAT mDxgiFormat = DXGI_FORMAT_UNKNOWN;
134
135 void Load();
136
137 private:
138 void LoadFile(const std::filesystem::path& pFilepath);
139#if ARCDPS_EXTENSION_CURL
140 void LoadUrl(const std::string& pUrl);
141 void LoadGw2Dat(const std::string& pId);
142#endif
143 void LoadResource(UINT pId);
144 void LoadFrame(const CComPtr<IWICBitmapFrameDecode>& pIDecodeFrame, const CComPtr<IWICImagingFactory>& pIWICFactory);
145 void DeviceLoad();
146 static DXGI_FORMAT GetFormatDx11(WICPixelFormatGUID pPixelFormat);
147
148 friend IconLoader;
149 };
150
151 HMODULE mDll;
152 ID3D11Device* mD11Device;
153
154 std::unordered_map<IconLoaderKeyType, Icon> mIcons;
155 std::unordered_map<IconLoaderKeyType, QueueIcon> mLoadQueue;
156 std::mutex mLoadQueueMutex;
157 std::queue<QueueIcon> mThreadQueue;
158
159 std::jthread mThread;
160 std::mutex mThreadMutex;
161 std::condition_variable_any mThreadVariable;
162
163 void runner(std::stop_token pToken);
164 void queueLoad(const QueueIcon& pIcon);
165 void loadDone(const IconLoader::QueueIcon& pIcon, ID3D11ShaderResourceView* pTexture);
166 };
167} // namespace ArcdpsExtension
168
169void ArcdpsExtension::IconLoader::RegisterFile(IconLoaderKey auto pName, const std::filesystem::path& pFilepath) {
170 std::lock_guard guard(mThreadMutex);
171
172 mThreadQueue.emplace(static_cast<IconLoaderKeyType>(pName), *this, LoadWay::File, pFilepath);
173
174 mThreadVariable.notify_one();
175}
176
177void ArcdpsExtension::IconLoader::RegisterUrl(IconLoaderKey auto pName, const std::string& pUrl) {
178 std::lock_guard guard(mThreadMutex);
179
180 mThreadQueue.emplace(static_cast<IconLoaderKeyType>(pName), *this, LoadWay::Url, pUrl);
181
182 mThreadVariable.notify_one();
183}
184
185void ArcdpsExtension::IconLoader::RegisterGw2Dat(IconLoaderKey auto pName, const std::string& pId) {
186 std::lock_guard guard(mThreadMutex);
187
188 mThreadQueue.emplace(static_cast<IconLoaderKeyType>(pName), *this, LoadWay::Gw2Dat, pId);
189
190 mThreadVariable.notify_one();
191}
192
194 std::lock_guard guard(mThreadMutex);
195
196 mThreadQueue.emplace(static_cast<IconLoaderKeyType>(pName), *this, LoadWay::Resource, pId);
197
198 mThreadVariable.notify_one();
199}
200
201ID3D11ShaderResourceView* ArcdpsExtension::IconLoader::Draw(IconLoaderKey auto pName) {
202 auto name = static_cast<IconLoaderKeyType>(pName);
203 if (const auto& icon = mIcons.find(name); icon != mIcons.end()) {
204 return icon->second.Texture;
205 }
206 if (const auto& icon = mLoadQueue.find(name); icon != mLoadQueue.end()) {
207 std::unique_lock lock(mLoadQueueMutex);
208 auto element = mLoadQueue.extract(name);
209 lock.unlock();
210
211 element.mapped().DeviceLoad();
212 }
213 return nullptr;
214}
Definition IconLoader.h:60
void RegisterFile(IconLoaderKey auto pName, const std::filesystem::path &pFilepath)
Definition IconLoader.h:169
~IconLoader() override
Definition IconLoader.cpp:109
void RegisterGw2Dat(IconLoaderKey auto pName, const std::string &pId)
Definition IconLoader.h:185
ID3D11ShaderResourceView * Draw(IconLoaderKey auto pName)
Definition IconLoader.h:201
void RegisterUrl(IconLoaderKey auto pName, const std::string &pUrl)
Definition IconLoader.h:177
void RegisterResource(IconLoaderKey auto pName, UINT pId)
Definition IconLoader.h:193
Definition Singleton.h:48
Definition IconLoader.h:34
Definition IconLoader.h:27
Definition ArcdpsExtension.h:10
uint64_t IconLoaderKeyType
Definition IconLoader.h:31