]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/layers/SimpleLayers.java
Bringing layers back to life
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / layers / SimpleLayers.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.layers;
13
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.Set;
17 import java.util.TreeSet;
18 import java.util.concurrent.CopyOnWriteArrayList;
19
20 import org.simantics.utils.strings.AlphanumComparator;
21
22 /**
23  * @author Antti Villberg
24  */
25 public class SimpleLayers implements ILayersEditor {
26
27     private static final Comparator<ILayer> LAYER_COMPARATOR = new Comparator<ILayer>() {
28         @Override
29         public int compare(ILayer o1, ILayer o2) {
30             return AlphanumComparator.COMPARATOR.compare(o1.getName(), o2.getName());
31         }
32     };
33
34     private Set<ILayer>                                 all                      = new TreeSet<ILayer>(LAYER_COMPARATOR);
35     private volatile Set<ILayer>                        allSnapshot;
36
37     private Set<ILayer>                                 visible                  = new TreeSet<ILayer>(LAYER_COMPARATOR);
38     private volatile Set<ILayer>                        visibleSnapshot;
39
40     private CopyOnWriteArrayList<ILayersEditorListener> layerEditorListeners     = new CopyOnWriteArrayList<ILayersEditorListener>();
41     private CopyOnWriteArrayList<ILayersListener>       layersListeners          = new CopyOnWriteArrayList<ILayersListener>();
42
43     private boolean                                     ignoreFocusSettings      = false;
44
45     private boolean                                     ignoreVisibilitySettings = false;
46
47     public SimpleLayers() {
48     }
49
50     public SimpleLayers(String... content) {
51         for (String s : content) {
52             ILayer layer = new SimpleLayer(s);
53             all.add(layer);
54             visible.add(layer);
55         }
56     }
57     
58     @Override
59     public void update(Set<ILayer> allLayers, Set<ILayer> visibleLayers) {
60         synchronized (this) {
61             all.clear();
62             all.addAll(allLayers);
63             visible.clear();
64             visible.addAll(visibleLayers);
65             allSnapshot = null;
66             visibleSnapshot = null;
67         }
68         for (ILayersListener listener : layersListeners) {
69             listener.changed();
70         }
71     }
72
73     @Override
74     public Set<ILayer> getLayers() {
75         // Double-checked locking idiom: http://en.wikipedia.org/wiki/Double-checked_locking
76         // Works with acquire/release semantics for volatile
77         // Broken under Java 1.4 and earlier semantics for volatile
78         if (allSnapshot == null) {
79             synchronized (this) {
80                 if (allSnapshot == null) {
81                     TreeSet<ILayer> ss = new TreeSet<ILayer>(LAYER_COMPARATOR);
82                     ss.addAll(all);
83                     allSnapshot = Collections.unmodifiableSet(ss);
84                 }
85             }
86         }
87         return allSnapshot;
88     }
89
90     @Override
91     public Set<ILayer> getVisibleLayers() {
92         // Double-checked locking idiom: http://en.wikipedia.org/wiki/Double-checked_locking
93         // Works with acquire/release semantics for volatile
94         // Broken under Java 1.4 and earlier semantics for volatile
95         if (visibleSnapshot == null) {
96             synchronized (this) {
97                 if (visibleSnapshot == null) {
98                     TreeSet<ILayer> ss = new TreeSet<ILayer>(LAYER_COMPARATOR);
99                     ss.addAll(visible);
100                     visibleSnapshot = Collections.unmodifiableSet(ss);
101                 }
102             }
103         }
104         return visibleSnapshot;
105     }
106
107     @Override
108     public boolean isActive(ILayer layer) {
109         synchronized (this) {
110             return visible.contains(layer);
111         }
112     }
113
114     @Override
115     public void deactivate(ILayer layer) {
116         boolean deactivated = false;
117         synchronized (this) {
118             deactivated = visible.remove(layer);
119         }
120         if (deactivated) {
121             synchronized (this) {
122                 visibleSnapshot = null;
123             }
124             for (ILayersListener listener : layersListeners) {
125                 listener.changed();
126             }
127             for (ILayersEditorListener listener : layerEditorListeners) {
128                 listener.layerDeactivated(layer);
129             }
130         }
131     }
132
133     @Override
134     public void activate(ILayer layer) {
135         boolean activated = false;
136         synchronized (this) {
137             activated = visible.add(layer);
138         }
139         if (activated) {
140             synchronized (this) {
141                 visibleSnapshot = null;
142             }
143             for (ILayersListener listener : layersListeners) {
144                 listener.changed();
145             }
146             for (ILayersEditorListener listener : layerEditorListeners) {
147                 listener.layerActivated(layer);
148             }
149         }
150     }
151
152     @Override
153     public void addLayer(ILayer layer) {
154         boolean added = false;
155         synchronized (this) {
156             added = all.add(layer);
157         }
158         if (added) {
159             synchronized (this) {
160                 allSnapshot = null;
161             }
162             for (ILayersListener listener : layersListeners) {
163                 listener.changed();
164             }
165             for (ILayersEditorListener listener : layerEditorListeners) {
166                 listener.layerAdded(layer);
167             }
168         }
169     }
170
171     @Override
172     public void removeLayer(ILayer layer) {
173         boolean removed = false;
174         synchronized (this) {
175             removed = all.remove(layer);
176             visible.remove(layer);
177         }
178         if (removed) {
179             synchronized (this) {
180                 allSnapshot = null;
181                 visibleSnapshot = null;
182             }
183             for (ILayersListener listener : layersListeners) {
184                 listener.changed();
185             }
186             for (ILayersEditorListener listener : layerEditorListeners) {
187                 listener.layerRemoved(layer);
188             }
189         }
190     }
191
192     @Override
193     public void addLayerEditorListener(ILayersEditorListener listener) {
194         layerEditorListeners.add(listener);
195     }
196
197     @Override
198     public void removeLayerEditorListener(ILayersEditorListener listener) {
199         layerEditorListeners.remove(listener);
200     }
201
202     @Override
203     public void addLayersListener(ILayersListener listener) {
204         layersListeners.add(listener);
205     }
206
207     @Override
208     public void removeLayersListener(ILayersListener listener) {
209         layersListeners.remove(listener);
210     }
211
212     @Override
213     public boolean getIgnoreFocusSettings() {
214         return ignoreFocusSettings;
215     }
216
217     @Override
218     public void setIgnoreFocusSettings(boolean value) {
219         boolean changed = ignoreFocusSettings != value;
220         ignoreFocusSettings = value;
221         if (changed) {
222             for (ILayersListener listener : layersListeners) {
223                 listener.changed();
224             }
225             for (ILayersEditorListener listener : layerEditorListeners) {
226                 listener.ignoreFocusChanged(value);
227             }
228         }
229     }
230
231     @Override
232     public boolean getIgnoreVisibilitySettings() {
233         return ignoreVisibilitySettings;
234     }
235
236     @Override
237     public void setIgnoreVisibilitySettings(boolean value) {
238         boolean changed = ignoreVisibilitySettings != value;
239         ignoreVisibilitySettings = value;
240         if (changed) {
241             for (ILayersListener listener : layersListeners) {
242                 listener.changed();
243             }
244             for (ILayersEditorListener listener : layerEditorListeners) {
245                 listener.ignoreVisibilityChanged(value);
246             }
247         }
248     }
249
250 }