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