Etterna 0.74.4
Loading...
Searching...
No Matches
RageUtil_CachedObject.h
1#ifndef RAGE_UTIL_CACHED_OBJECT_H
2#define RAGE_UTIL_CACHED_OBJECT_H
3
4#include <set>
5
6template<typename T>
8
12void
13Lock();
14void
15Unlock();
16}
17
19template<typename T>
21{
22 public:
24 : m_pObject(nullptr)
25 {
26 /* A new object is being constructed, so invalidate negative caching. */
27 ClearCacheNegative();
28 }
29
30 CachedObject(const CachedObject& cpy)
31 : m_pObject(nullptr)
32 {
33 ClearCacheNegative();
34 }
35
37 {
38 if (m_pObject != nullptr)
39 ClearCacheSpecific(m_pObject);
40 }
41
42 auto operator=(const CachedObject& rhs) -> CachedObject& { return *this; }
43
44 /* Clear all cached entries for this type. */
45 static void ClearCacheAll()
46 {
47 CachedObjectHelpers::Lock();
48 for (typename std::set<ObjectPointer*>::iterator p =
49 m_spObjectPointers.begin();
50 p != m_spObjectPointers.end();
51 ++p) {
52 (*p)->m_pCache = nullptr;
53 (*p)->m_bCacheIsSet = false;
54 }
55 CachedObjectHelpers::Unlock();
56 }
57
58 /* Clear all cached entries pointing to a specific object. */
59 static void ClearCacheSpecific(const T* pObject)
60 {
61 CachedObjectHelpers::Lock();
62 for (typename std::set<ObjectPointer*>::iterator p =
63 m_spObjectPointers.begin();
64 p != m_spObjectPointers.end();
65 ++p) {
66 if ((*p)->m_pCache == pObject) {
67 (*p)->m_pCache = nullptr;
68 (*p)->m_bCacheIsSet = false;
69 }
70 }
71 CachedObjectHelpers::Unlock();
72 }
73
74 /* Clear all negative cached entries of this type. */
75 static void ClearCacheNegative()
76 {
77 CachedObjectHelpers::Lock();
78 for (typename std::set<ObjectPointer*>::iterator p =
79 m_spObjectPointers.begin();
80 p != m_spObjectPointers.end();
81 ++p) {
82 if ((*p)->m_pCache == nullptr)
83 (*p)->m_bCacheIsSet = false;
84 }
85 CachedObjectHelpers::Unlock();
86 }
87
88 private:
90 friend class CachedObjectPointer<T>;
91
92 static void Register(ObjectPointer* p) { m_spObjectPointers.insert(p); }
93
94 static void Unregister(ObjectPointer* p)
95 {
96 typename std::set<ObjectPointer*>::iterator it =
97 m_spObjectPointers.find(p);
98 ASSERT(it != m_spObjectPointers.end());
99 m_spObjectPointers.erase(it);
100 }
101
102 /* This points to the actual T this object is contained in. This is set
103 * the first time CachedObjectPointer::Set() is called for this object.
104 * That's more convenient than setting it ourselves; we don't need to
105 * do anything special in T's copy ctor. This works because there's no
106 * need to clear cache for an object before any CachedObjectPointers have
107 * ever been set for it. */
108 const T* m_pObject;
109 static std::set<ObjectPointer*> m_spObjectPointers;
110};
111template<typename T>
112std::set<CachedObjectPointer<T>*> CachedObject<T>::m_spObjectPointers =
113 std::set<CachedObjectPointer<T>*>();
114
115template<typename T>
117{
118 public:
119 using Object = CachedObject<T>;
120
122 : m_pCache(nullptr)
123 {
124 Object::Register(this);
125 }
126
128 : m_pCache(cpy.m_pCache)
129 , m_bCacheIsSet(cpy.m_bCacheIsSet)
130 {
131 CachedObjectHelpers::Lock();
132 Object::Register(this);
133 CachedObjectHelpers::Unlock();
134 }
135
136 ~CachedObjectPointer() { Object::Unregister(this); }
137
138 auto Get(T** pRet) const -> bool
139 {
140 CachedObjectHelpers::Lock();
141 if (!m_bCacheIsSet) {
142 CachedObjectHelpers::Unlock();
143 return false;
144 }
145 *pRet = m_pCache;
146 CachedObjectHelpers::Unlock();
147 return true;
148 }
149
150 void Set(T* p)
151 {
152 CachedObjectHelpers::Lock();
153 m_pCache = p;
154 m_bCacheIsSet = true;
155 if (p != nullptr)
156 p->m_CachedObject.m_pObject = p;
157 CachedObjectHelpers::Unlock();
158 }
159
160 void Unset()
161 {
162 CachedObjectHelpers::Lock();
163 m_pCache = nullptr;
164 m_bCacheIsSet = false;
165 CachedObjectHelpers::Unlock();
166 }
167
168 private:
169 friend class CachedObject<T>;
170
171 T* m_pCache;
172 bool m_bCacheIsSet{ false };
173};
174
175#endif
Definition RageUtil_CachedObject.h:117
Cached object pointers with automatic invalidation.
Definition RageUtil_CachedObject.h:21
Utilities for working with the CachedObjects.
Definition RageUtil_CachedObject.h:11