summaryrefslogtreecommitdiff
path: root/Runtime/Misc/CachingManager.h
blob: 4d7822130fc1551b2bf1cd53224e3b684245c957 (plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#ifndef CACHINGMANAGER_H
#define CACHINGMANAGER_H

#include "Runtime/Misc/AssetBundle.h"

class Cache;

#if ENABLE_CACHING

#include "PreloadManager.h"

class CachedUnityWebStream
{
	public:
	SInt32        m_Version;
	std::vector<std::string> m_Files;
};

class AsyncCachedUnityWebStream : public PreloadManagerOperation
{
	int				m_InstanceID;
	AssetBundle*    m_LoadingAssetBundle;
	std::string		m_Url;
	std::string		m_Error;
	int				m_Version;
	UInt32			m_RequestedCRC;
	bool			m_AssetBundleWithSameNameIsAlreadyLoaded;

	friend class CachingManager;

	void LoadCachedUnityWebStream();
public:

	AsyncCachedUnityWebStream ();
	~AsyncCachedUnityWebStream ();

	AssetBundle* GetAssetBundle () { return PPtr<AssetBundle> (m_InstanceID); }
	bool DidSucceed() { return IsDone() && m_InstanceID != 0;}
	bool AssetBundleWithSameNameIsAlreadyLoaded() { return m_AssetBundleWithSameNameIsAlreadyLoaded; }
	virtual void Perform ();

	virtual void IntegrateMainThread ();
	virtual bool HasIntegrateMainThread () { return true; }
	std::string &GetError() { return m_Error; }

#if ENABLE_PROFILER
	virtual std::string GetDebugName () { return "AsyncCachedUnityWebStream"; }
#endif
};

class Cache : public NonCopyable
{
public:
	bool m_IncludePlayerURL;
	string m_Name;
	time_t m_Expires;
	long long m_BytesUsed;
	long long m_BytesAvailable; // bytes allowed
	long long m_MaxLicenseBytesAvailable; // Bytes allowed by the license

	int GetExpirationDelay () { return m_CacheExpirationDelay; }
	void SetExpirationDelay (int expiration);

	void WriteCacheInfoFile (bool updateExpiration);
	string GetFolder (const string& path, bool create);

	void AddToCache (const string &path, int bytes);
	void UpdateTimestamp (const std::string &path, time_t lastAccessed);

	bool CleanCache ();

	bool FreeSpace (size_t bytes);

	void SetMaximumDiskSpaceAvailable (long long maxUsage);
	long long GetMaximumDiskSpaceAvailable () { return m_BytesAvailable; }

	long long GetCachingDiskSpaceUsed () { return m_BytesUsed; }
	long long GetCachingDiskSpaceFree () { return m_BytesAvailable - m_BytesUsed; }
	bool GetIsReady () { return m_Ready; }

	bool ReadCacheIndex (const string& name, bool getSize);
	string URLToPath (const string& url, int version);

	Cache();
	~Cache();

private:
	struct CachedFile
	{
		string path;
		size_t size;
		int version;
		time_t lastAccessed;

		CachedFile()
		{
			size = version = lastAccessed = 0;
		}
		CachedFile(string _path, size_t _size, int _version, time_t _lastAccessed)
		{
			path = _path;
			size = _size;
			version = _version;
			lastAccessed = _lastAccessed;
		}
		bool operator < (const CachedFile& other) const
		{
			return lastAccessed < other.lastAccessed;
		}
	};

	typedef std::multiset<CachedFile> CachedFiles;

	int         m_CacheExpirationDelay;
	Thread      m_IndexThread;
	Mutex       m_Mutex;
	bool        m_Ready;
	CachedFiles m_CachedFiles;

	bool ReadCacheInfoFile (const string& path, time_t *expires, time_t *oldestLastUsedTime);
	static void *ReadCacheIndexThreaded (void *data);
};

class CachingManager
{
public:
	enum AuthorizationLevel
	{
		kAuthorizationNone = 0,
		kAuthorizationUser,
		kAuthorizationAdmin
	};
	enum
	{
		kMaxCacheExpiration = (150 * 86400) //150 days
	};

	CachingManager ();
	~CachingManager ();
	void Reset ();

	std::string GetTempFolder ();
	static bool MoveTempFolder (const string& from, const string& to);
	static time_t GenerateTimeStamp ();
	static int WriteInfoFile (const std::string &path, const std::vector<std::string> &fileNames);
	static int WriteInfoFile (const std::string &path, const std::vector<std::string> &fileNames, time_t lastAccessed);
	static bool ReadInfoFile (const std::string &path, time_t *lastUsedTime, std::vector<std::string> *fileNames);

	std::vector<Cache*> &GetCacheIndices ();

	bool CleanCache (std::string name);

	bool Authorize (const string &name, const string &domain, long long size, int expiration, const string &signature);
	AuthorizationLevel GetAuthorizationLevel ();

	AsyncCachedUnityWebStream* LoadCached (const std::string& url, int version, UInt32 crc);
	bool IsCached (const std::string &url, int version);
	bool MarkAsUsed (const std::string& url, int version);

	bool GetEnabled () { return m_Enabled; }
	void SetEnabled (bool enabled);


	Cache& GetCurrentCache();

	long long GetCachingDiskSpaceUsed ();
	long long GetCachingDiskSpaceFree ();

	void SetMaximumDiskSpaceAvailable (long long maximumAvailable);
	long long GetMaximumDiskSpaceAvailable ();

	int GetExpirationDelay ();
	bool GetIsReady ();

#if UNITY_IPHONE
	void SetNoBackupFlag(const std::string &url, int version);
	void ResetNoBackupFlag(const std::string &url, int version);
#endif

private:
	AuthorizationLevel m_Authorization;
	Cache* m_Cache;
	bool m_Enabled;

	void Dispose ();
	void ClearTempFolder();
	bool VerifyValidDomain (const std::string &domain);
	void SetCurrentCache (const string &name, long long size, bool includePlayerURL);
	void ReadCacheIndices (std::vector<Cache*> &indices, bool getSize);
};

/// Handles the cache for multiple games
class GlobalCachingManager
{
	std::vector<Cache*>* m_CacheIndices;
	void ReadCacheIndices (std::vector<Cache*> &indices, bool getSize);

public:
	GlobalCachingManager ()
	{
		m_CacheIndices = NULL;
	}

	std::vector<Cache*>& GetCacheIndices ();
	void ClearAllExpiredCaches ();
	void RebuildAllCaches ();
	void Dispose ();
};


CachingManager &GetCachingManager();
GlobalCachingManager &GetGlobalCachingManager();

#endif // ENABLE_CACHING
#endif