/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.layers; import java.util.Collections; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CopyOnWriteArrayList; /** * @author Antti Villberg */ public class SimpleLayers implements ILayersEditor { private static final Comparator LAYER_COMPARATOR = new Comparator() { @Override public int compare(ILayer o1, ILayer o2) { return o1.getName().compareTo(o2.getName()); } }; private Set all = new TreeSet(LAYER_COMPARATOR); private volatile Set allSnapshot; private Set visible = new TreeSet(LAYER_COMPARATOR); private volatile Set visibleSnapshot; private CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); private boolean ignoreFocusSettings = false; private boolean ignoreVisibilitySettings = false; public SimpleLayers() { } public SimpleLayers(String... content) { for (String s : content) { ILayer layer = new SimpleLayer(s); all.add(layer); visible.add(layer); } allSnapshot = null; visibleSnapshot = null; } @Override public Set getLayers() { // Double-checked locking idiom: http://en.wikipedia.org/wiki/Double-checked_locking // Works with acquire/release semantics for volatile // Broken under Java 1.4 and earlier semantics for volatile if (allSnapshot == null) { synchronized (this) { if (allSnapshot == null) { TreeSet ss = new TreeSet(LAYER_COMPARATOR); ss.addAll(all); allSnapshot = Collections.unmodifiableSet(ss); } } } return allSnapshot; } @Override public Set getVisibleLayers() { // Double-checked locking idiom: http://en.wikipedia.org/wiki/Double-checked_locking // Works with acquire/release semantics for volatile // Broken under Java 1.4 and earlier semantics for volatile if (visibleSnapshot == null) { synchronized (this) { if (visibleSnapshot == null) { TreeSet ss = new TreeSet(LAYER_COMPARATOR); ss.addAll(visible); visibleSnapshot = Collections.unmodifiableSet(ss); } } } return visibleSnapshot; } @Override public boolean isActive(ILayer layer) { synchronized (this) { return visible.contains(layer); } } @Override public void deactivate(ILayer layer) { boolean deactivated = false; synchronized (this) { deactivated = visible.remove(layer); } if (deactivated) { synchronized (this) { visibleSnapshot = null; } for (ILayersEditorListener listener : listeners) { listener.layerDeactivated(layer); } } } @Override public void activate(ILayer layer) { boolean activated = false; synchronized (this) { activated = visible.add(layer); } if (activated) { synchronized (this) { visibleSnapshot = null; } for (ILayersEditorListener listener : listeners) { listener.layerActivated(layer); } } } @Override public void addLayer(ILayer layer) { boolean added = false; synchronized (this) { added = all.add(layer); } if (added) { synchronized (this) { allSnapshot = null; } for (ILayersEditorListener listener : listeners) { listener.layerAdded(layer); } } } @Override public void removeLayer(ILayer layer) { boolean removed = false; synchronized (this) { removed = all.remove(layer); visible.remove(layer); } if (removed) { synchronized (this) { allSnapshot = null; visibleSnapshot = null; } for (ILayersEditorListener listener : listeners) { listener.layerRemoved(layer); } } } @Override public void addListener(ILayersEditorListener listener) { listeners.add(listener); } @Override public void removeListener(ILayersEditorListener listener) { listeners.remove(listener); } @Override public boolean getIgnoreFocusSettings() { return ignoreFocusSettings; } @Override public void setIgnoreFocusSettings(boolean value) { boolean changed = ignoreFocusSettings != value; ignoreFocusSettings = value; if (changed) { for (ILayersEditorListener listener : listeners) { listener.ignoreFocusChanged(value); } } } @Override public boolean getIgnoreVisibilitySettings() { return ignoreVisibilitySettings; } @Override public void setIgnoreVisibilitySettings(boolean value) { boolean changed = ignoreVisibilitySettings != value; ignoreVisibilitySettings = value; if (changed) { for (ILayersEditorListener listener : listeners) { listener.ignoreVisibilityChanged(value); } } } }