forked from rainmeter/rainmeter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImageCache.h
121 lines (95 loc) · 3.04 KB
/
ImageCache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Copyright (C) 2018 Rainmeter Project Developers
*
* This Source Code Form is subject to the terms of the GNU General Public
* License; either version 2 of the License, or (at your option) any later
* version. If a copy of the GPL was not distributed with this file, You can
* obtain one at <https://www.gnu.org/licenses/gpl-2.0.html>. */
#ifndef __IMAGECACHE_H__
#define __IMAGECACHE_H__
#include <unordered_map>
#include <map>
#include <string>
#include <../Common/Gfx/D2DBitmap.h>
#include "ImageOptions.h"
class ImageCachePool;
namespace std {
template <> struct hash<ImageOptions>
{
std::size_t operator()(const ImageOptions& opt) const noexcept
{
size_t res = 17;
res = res * 31 + std::hash<std::wstring>()(opt.m_Path);
res = res * 31 + std::hash<DWORD>()(opt.m_FileSize);
res = res * 31 + std::hash<ULONGLONG>()(opt.m_FileTime);
res = res * 31 + std::hash<FLOAT>()(opt.m_Rotate);
res = res * 31 + std::hash<FLOAT>()(opt.m_Crop.left);
res = res * 31 + std::hash<FLOAT>()(opt.m_Crop.top);
res = res * 31 + std::hash<FLOAT>()(opt.m_Crop.right);
res = res * 31 + std::hash<FLOAT>()(opt.m_Crop.bottom);
res = res * 31 + std::hash<INT>()((INT)opt.m_CropMode);
res = res * 31 + std::hash<INT>()((INT)opt.m_Flip);
res = res * 31 + std::hash<bool>()(opt.m_GreyScale);
res = res * 31 + std::hash<bool>()(opt.m_UseExifOrientation);
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 4; ++j)
{
res = res * 31 + std::hash<FLOAT>()(opt.m_ColorMatrix.m[i][j]);
}
}
return res;
}
};
} // namespace std
struct ImageCache
{
ImageCache(const ImageOptions& key, Gfx::D2DBitmap* bitmap, ImageCachePool* pool) :
m_Key(key),
m_Bitmap(bitmap),
m_Pool(pool),
m_Instances(0U)
{ }
~ImageCache()
{
delete m_Bitmap;
m_Bitmap = nullptr;
}
void Update(const ImageOptions& key, Gfx::D2DBitmap* item);
ImageOptions m_Key;
Gfx::D2DBitmap* m_Bitmap;
ImageCachePool* m_Pool;
UINT m_Instances;
};
struct ImageCacheHandle
{
Gfx::D2DBitmap* GetBitmap() const { return m_Cache->m_Bitmap; }
ImageOptions& GetKey() const { return m_Cache->m_Key; }
ImageCacheHandle(ImageCacheHandle&) = delete;
ImageCacheHandle& operator=(ImageCacheHandle other) = delete;
~ImageCacheHandle();
private:
friend class ImageCachePool;
ImageCacheHandle(ImageCache* cache) : m_Cache(cache)
{
++cache->m_Instances;
}
ImageCache* m_Cache;
};
class ImageCachePool
{
public:
static ImageCachePool& GetInstance();
ImageCacheHandle* Get(const ImageOptions& key);
void Put(const ImageOptions& key, Gfx::D2DBitmap* item);
private:
friend struct ImageCacheHandle;
ImageCachePool();
~ImageCachePool();
ImageCachePool(const ImageCachePool& other) = delete;
ImageCachePool& operator=(ImageCachePool other) = delete;
void Remove(const ImageOptions& item);
std::unordered_map<ImageOptions, ImageCache*> m_CachePool;
};
// Convenience function.
inline ImageCachePool& GetImageCache() { return ImageCachePool::GetInstance(); }
#endif