Add license text to the top of every source file.
[Tsunagari.git] / src / cache.h
blob960d9fa289df249f247975f2f0d5acabc4543d6a
1 /****************************
2 ** Tsunagari Tile Engine **
3 ** cache.h **
4 ** Copyright 2012 OmegaSDG **
5 ****************************/
7 // **********
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // **********
27 #ifndef CACHE_H
28 #define CACHE_H
30 #include <string>
31 #include <vector>
33 #include "client-conf.h"
34 #include "log.h"
35 #include "window.h"
37 #include <boost/foreach.hpp>
38 #include <boost/unordered_map.hpp>
40 #define IN_USE_NOW -1
42 template<class T>
43 class Cache
45 public:
46 T momentaryRequest(const std::string& name)
48 if (conf.cacheEnabled) {
49 typename CacheMap::iterator it = map.find(name);
50 if (it != map.end()) {
51 // Log::info("Cache", name + ": requested (cached)");
52 CacheEntry& entry = it->second;
53 // Set lastUsed to now because it won't be used
54 // by the time garbageCollect() gets to it.
55 entry.lastUsed = GameWindow::instance().time();
56 return entry.resource;
59 Log::info("Cache", name + ": requested");
60 return T();
63 T lifetimeRequest(const std::string& name)
65 if (conf.cacheEnabled) {
66 typename CacheMap::iterator it = map.find(name);
67 if (it != map.end()) {
68 // Log::info("Cache", name + ": requested (cached)");
69 CacheEntry& entry = it->second;
70 entry.lastUsed = IN_USE_NOW;
71 return entry.resource;
74 Log::info("Cache", name + ": requested");
75 return T();
78 void momentaryPut(const std::string& name, T data)
80 if (!conf.cacheEnabled)
81 return;
82 CacheEntry entry;
83 entry.resource = data;
84 time_t now = GameWindow::instance().time();
85 entry.lastUsed = now;
86 map[name] = entry;
89 void lifetimePut(const std::string& name, T data)
91 if (!conf.cacheEnabled)
92 return;
93 CacheEntry entry;
94 entry.resource = data;
95 entry.lastUsed = IN_USE_NOW;
96 map[name] = entry;
99 void garbageCollect()
101 if (!conf.cacheEnabled)
102 return;
103 time_t now = GameWindow::instance().time();
104 std::vector<std::string> dead;
105 BOOST_FOREACH(typename CacheMap::value_type& i, map) {
106 const std::string& name = i.first;
107 CacheEntry& cache = i.second;
108 bool unused = !cache.resource || cache.resource.unique();
109 if (!unused)
110 continue;
111 if (cache.lastUsed == IN_USE_NOW) {
112 cache.lastUsed = now;
113 // Log::info("Resourcer", name + ": unused");
115 else if (now > cache.lastUsed + conf.cacheTTL*1000) {
116 dead.push_back(name);
117 Log::info("Cache", name + ": purged");
120 BOOST_FOREACH(const std::string& name, dead)
121 map.erase(name);
124 private:
125 struct CacheEntry
127 T resource;
128 time_t lastUsed;
129 size_t memoryUsed;
132 typedef boost::unordered_map<const std::string, CacheEntry> CacheMap;
133 CacheMap map;
136 #endif