]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GECache.java
ac911a458fe0dedf99fb5e376f078748e88eb657
[simantics/platform.git] / bundles / org.simantics.browsing.ui.common / src / org / simantics / browsing / ui / common / internal / GECache.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.common.internal;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 import gnu.trove.map.hash.TObjectIntHashMap;\r
16 import gnu.trove.set.hash.THashSet;\r
17 \r
18 import java.util.Collections;\r
19 import java.util.Map;\r
20 import java.util.Set;\r
21 \r
22 import org.simantics.browsing.ui.NodeContext;\r
23 import org.simantics.browsing.ui.NodeContext.CacheKey;\r
24 \r
25 public class GECache implements IGECache {\r
26 \r
27     final Map<GECacheKey, IGECacheEntry> entries = new THashMap<GECacheKey, IGECacheEntry>();\r
28     final Map<GECacheKey, Set<UIElementReference>> treeReferences = new THashMap<GECacheKey, Set<UIElementReference>>();\r
29 \r
30     final private static class GECacheKey {\r
31 \r
32         private NodeContext context;\r
33         private CacheKey<?> key;\r
34 \r
35         GECacheKey(NodeContext context, CacheKey<?> key) {\r
36             this.context = context;\r
37             this.key = key;\r
38             if (context == null || key == null) \r
39                 throw new IllegalArgumentException("Null context or key is not accepted");\r
40         }\r
41 \r
42         GECacheKey(GECacheKey other) {\r
43             this.context = other.context;\r
44             this.key = other.key;\r
45             if (context == null || key == null) \r
46                 throw new IllegalArgumentException("Null context or key is not accepted");\r
47         }\r
48 \r
49         void setValues(NodeContext context, CacheKey<?> key) {\r
50             this.context = context;\r
51             this.key = key;\r
52             if (context == null || key == null) \r
53                 throw new IllegalArgumentException("Null context or key is not accepted");\r
54         }\r
55 \r
56         @Override\r
57         public int hashCode() {\r
58             return context.hashCode() | key.hashCode();\r
59         }\r
60 \r
61         @Override\r
62         public boolean equals(Object object) {\r
63 \r
64             if (this == object)\r
65                 return true;\r
66             else if (object == null)\r
67                 return false;\r
68 //            else if (getClass() != object.getClass())\r
69 //                return false;\r
70 \r
71             GECacheKey i = (GECacheKey)object;\r
72 \r
73             return key.equals(i.key) && context.equals(i.context);\r
74 \r
75         }\r
76 \r
77     };\r
78 \r
79     /**\r
80      * This single instance is used for all get operations from the cache. This\r
81      * should work since the GE cache is meant to be single-threaded within the\r
82      * current UI thread, what ever that thread is. For put operations which\r
83      * store the key, this is not used.\r
84      */\r
85     NodeContext getNC = new NodeContext() {\r
86         @SuppressWarnings("rawtypes")\r
87                 @Override\r
88         public Object getAdapter(Class adapter) {\r
89                 return null;\r
90         }\r
91         \r
92         @Override\r
93         public <T> T getConstant(ConstantKey<T> key) {\r
94                 return null;\r
95         }\r
96         \r
97         @Override\r
98         public Set<ConstantKey<?>> getKeys() {\r
99                 return Collections.emptySet();\r
100         }\r
101     };\r
102     CacheKey<?> getCK = new CacheKey<Object>() {\r
103         @Override\r
104         public Object processorIdenfitier() {\r
105                 return this;\r
106         }\r
107         };\r
108     GECacheKey getKey = new GECacheKey(getNC, getCK);\r
109 \r
110     public <T> IGECacheEntry put(NodeContext context, CacheKey<T> key, T value) {\r
111         IGECacheEntry entry = new GECacheEntry(context, key, value);\r
112         entries.put(new GECacheKey(context, key), entry);\r
113         return entry;\r
114     }\r
115 \r
116     @SuppressWarnings("unchecked")\r
117     public <T> T get(NodeContext context, CacheKey<T> key) {\r
118         getKey.setValues(context, key);\r
119         IGECacheEntry entry = entries.get(getKey);\r
120         if (entry == null)\r
121             return null;\r
122         return (T) entry.getValue();\r
123     }\r
124 \r
125     @Override\r
126     public <T> IGECacheEntry getEntry(NodeContext context, CacheKey<T> key) {\r
127         assert(context != null);\r
128         assert(key != null);\r
129         getKey.setValues(context, key);\r
130         return entries.get(getKey);\r
131     }\r
132 \r
133     @Override\r
134     public <T> void remove(NodeContext context, CacheKey<T> key) {\r
135         getKey.setValues(context, key);\r
136         entries.remove(getKey);\r
137     }\r
138 \r
139     @Override\r
140     public <T> Set<UIElementReference> getTreeReference(NodeContext context, CacheKey<T> key) {\r
141         assert(context != null);\r
142         assert(key != null);\r
143         getKey.setValues(context, key);\r
144         return treeReferences.get(getKey);\r
145     }\r
146 \r
147     @Override\r
148     public <T> void putTreeReference(NodeContext context, CacheKey<T> key, UIElementReference reference) {\r
149         assert(context != null);\r
150         assert(key != null);\r
151         getKey.setValues(context, key);\r
152         Set<UIElementReference> refs = treeReferences.get(getKey);\r
153         if (refs != null) {\r
154             refs.add(reference);\r
155         } else {\r
156             refs = new THashSet<UIElementReference>(4);\r
157             refs.add(reference);\r
158             treeReferences.put(new GECacheKey(getKey), refs);\r
159         }\r
160     }\r
161 \r
162     @Override\r
163     public <T> Set<UIElementReference> removeTreeReference(NodeContext context, CacheKey<T> key) {\r
164         assert(context != null);\r
165         assert(key != null);\r
166         getKey.setValues(context, key);\r
167         return treeReferences.remove(getKey);\r
168     }\r
169     \r
170     @Override\r
171     public boolean isShown(NodeContext context) {\r
172         return references.get(context) > 0;\r
173     }\r
174 \r
175     private TObjectIntHashMap<NodeContext> references = new TObjectIntHashMap<NodeContext>();\r
176     \r
177     @Override\r
178     public void incRef(NodeContext context) {\r
179         int exist = references.get(context);\r
180         references.put(context, exist+1);\r
181     }\r
182     \r
183     @Override\r
184     public void decRef(NodeContext context) {\r
185         int exist = references.get(context);\r
186         references.put(context, exist-1);\r
187         if(exist == 1) {\r
188                 references.remove(context);\r
189         }\r
190     }\r
191     \r
192     public void dispose() {\r
193         references.clear();\r
194         entries.clear();\r
195         treeReferences.clear();\r
196     }\r
197     \r
198 }\r