summaryrefslogtreecommitdiff
path: root/deps/g3dlite/include/G3D/WeakCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/g3dlite/include/G3D/WeakCache.h')
-rw-r--r--deps/g3dlite/include/G3D/WeakCache.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/deps/g3dlite/include/G3D/WeakCache.h b/deps/g3dlite/include/G3D/WeakCache.h
new file mode 100644
index 0000000000..f9fdc4bbd5
--- /dev/null
+++ b/deps/g3dlite/include/G3D/WeakCache.h
@@ -0,0 +1,122 @@
+/**
+ @file WeakCache.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2007-05-16
+ @edited 2007-05-16
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_WEAKCACHE_H
+#define G3D_WEAKCACHE_H
+
+#include "G3D/ReferenceCount.h"
+#include "G3D/Table.h"
+
+namespace G3D {
+
+/**
+ A cache that does not prevent its members from being garbage collected.
+ Useful to avoid loading or computing an expression twice. Useful
+ for memoization and dynamic programming.
+
+ Maintains a table of weak pointers. Weak pointers do not prevent
+ an object from being garbage collected. If the object is garbage
+ collected, the cache removes its reference.
+
+ There are no "contains" or "iterate" methods because elements can be
+ flushed from the cache at any time if they are garbage collected.
+
+ Example:
+ <pre>
+ WeakCache<std::string, TextureRef> textureCache;
+
+ TextureRef loadTexture(std::string s) {
+ TextureRef t = textureCache[s];
+
+ if (t.isNull()) {
+ t = Texture::fromFile(s);
+ textureCache.set(s, t);
+ }
+
+ return t;
+ }
+
+
+ </pre>
+ */
+template<class Key, class ValueRef>
+class WeakCache {
+ typedef WeakReferenceCountedPointer<typename ValueRef::element_type> ValueWeakRef;
+
+private:
+
+ Table<Key, ValueWeakRef> table;
+
+public:
+ /**
+ Returns NULL if the object is not in the cache
+ */
+ ValueRef operator[](const Key& k) {
+ if (table.containsKey(k)) {
+ ValueWeakRef w = table[k];
+ ValueRef s = w.createStrongPtr();
+ if (s.isNull()) {
+ // This object has been collected; clean out its key
+ table.remove(k);
+ }
+ return s;
+ } else {
+ return NULL;
+ }
+ }
+
+ void set(const Key& k, ValueRef v) {
+ table.set(k, v);
+ }
+
+ /** Removes k from the cache or does nothing if it is not currently in the cache.*/
+ void remove(const Key& k) {
+ if (table.containsKey(k)) {
+ table.remove(k);
+ }
+ }
+};
+
+#if 0 // To turn off all WeakCaching
+template<class Key, class ValueRef>
+class WeakCache {
+private:
+
+ Table<Key, ValueRef> table;
+
+public:
+ /**
+ Returns NULL if the object is not in the cache
+ */
+ ValueRef operator[](const Key& k) {
+ if (table.containsKey(k)) {
+ return table[k];
+ } else {
+ return NULL;
+ }
+ }
+
+ void set(const Key& k, ValueRef v) {
+ table.set(k, v);
+ }
+
+ /** Removes k from the cache or does nothing if it is not currently in the cache.*/
+ void remove(const Key& k) {
+ if (table.containsKey(k)) {
+ table.remove(k);
+ }
+ }
+};
+#endif
+
+}
+#endif
+