Commit 61909052 authored by Nico Mack's avatar Nico Mack

Improved handling of tethers

parent d6cee3f5
......@@ -41,6 +41,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class managing tethering of tetherable objects. The manager maintains a list of potential
......@@ -58,8 +59,8 @@ import java.util.Map.Entry;
public class TetherManager {
private Tetherable tetherable;
private HashMap<Tetherable, Tether> potentialTethers;
private List<Tetherable> currentlyTethered;
private Map<Tetherable, Tether> potentialTethers;
private Map<Tetherable, Tether> currentlyTethered;
private boolean exclusive;
private TetherEventSource tetherListeners;
......@@ -90,8 +91,8 @@ public class TetherManager {
* @param exclusive
*/
public TetherManager(Tetherable tetherable, boolean exclusive) {
this.currentlyTethered = new ArrayList<>();
this.potentialTethers = new HashMap<>();
this.currentlyTethered = new ConcurrentHashMap<>();
this.potentialTethers = new ConcurrentHashMap<>();
this.tetherable = tetherable;
this.exclusive = exclusive;
this.tetheringEnabled = true;
......@@ -184,7 +185,7 @@ public class TetherManager {
if (!currentlyTethered.isEmpty()) {
synchronized (currentlyTethered) {
for (Tetherable tethered : currentlyTethered) {
for (Tetherable tethered : currentlyTethered.keySet()) {
Point tetherEnding = tethered.getTetherOrigin().toScreenCoordinates();
shortest = Math.min(this.distance(tetherOrigin, tetherEnding), shortest);
}
......@@ -204,7 +205,7 @@ public class TetherManager {
if (this.currentlyTethered.isEmpty())
return;
List<Tetherable> exTethers = new ArrayList<>(this.currentlyTethered);
List<Tetherable> exTethers = new ArrayList<>(this.currentlyTethered.keySet());
for (Tetherable exTether : exTethers) {
this.separateFrom(exTether, propagate);
}
......@@ -543,14 +544,15 @@ public class TetherManager {
}
if (this.potentialTethers.containsKey(candidate)) {
if (!this.currentlyTethered.contains(candidate)) {
if (!this.currentlyTethered.containsKey(candidate)) {
if (this.exclusive && !this.currentlyTethered.isEmpty()) {
// If no other tethers are allowed (exclusive mode), then we
// have to separate from previously tethered widgets/objects
this.separateFromAll(propagate);
}
this.currentlyTethered.add(candidate);
Tether tether = this.potentialTethers.get(candidate);
this.currentlyTethered.put(candidate, tether.clone());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} now tethered with {}!", this.tetherable, candidate); //$NON-NLS-1$
......@@ -581,7 +583,7 @@ public class TetherManager {
Preconditions.checkNotNull(tethered, "Tethered object MUST not be null!"); //$NON-NLS-1$
synchronized (this.currentlyTethered) {
if (this.currentlyTethered.contains(tethered)) {
if (this.currentlyTethered.containsKey(tethered)) {
this.currentlyTethered.remove(tethered);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} no longer tethered with {}!", this.tetherable, tethered); //$NON-NLS-1$
......@@ -622,7 +624,7 @@ public class TetherManager {
// ---------------------------------------------------------------------------
public boolean isTetheredWith(Tetherable candidate) {
return this.currentlyTethered.contains(candidate);
return this.currentlyTethered.containsKey(candidate);
}
// ---------------------------------------------------------------------------
......@@ -641,7 +643,7 @@ public class TetherManager {
public <T> List<T> getTethers(Class<T> tetherClass) {
List<T> tethers = new ArrayList<>();
for (Tetherable tethered : currentlyTethered) {
for (Tetherable tethered : currentlyTethered.keySet()) {
Tether tether = this.potentialTethers.get(tethered);
if (tetherClass.isAssignableFrom(tether.getClass()))
tethers.add((T) tether);
......@@ -661,9 +663,9 @@ public class TetherManager {
public void updateTethers(Graphics2D canvas) {
Tether tether;
Iterator<Tetherable> tetherIterator = currentlyTethered.iterator();
Iterator<Tether> tetherIterator = currentlyTethered.values().iterator();
while (tetherIterator.hasNext()) {
tether = this.potentialTethers.get(tetherIterator.next());
tether = tetherIterator.next();
tether.paint(canvas);
}
}
......@@ -715,10 +717,6 @@ public class TetherManager {
if ((distance <= tetheringDistance - HYSTERESIS) && (distance < shortestTether)) {
this.tetherable.tetherWith(potential, DO_PROPAGATE);
isTethered = true;
// Make sure to clone the Tether object so that multiple instances can coexist.
entry.setValue(entry.getValue().clone());
}
} else if (distance >= tetheringDistance + HYSTERESIS) {
if (!potential.isDraggable()) {
......@@ -738,9 +736,11 @@ public class TetherManager {
if (alreadyTetheredWith) {
Tether tether = entry.getValue();
tether.setOrigin(tetherOrigin);
tether.setEnding(tetherEnding);
Tether tether = this.currentlyTethered.get(potential);
if (tether != null) {
tether.setOrigin(tetherOrigin);
tether.setEnding(tetherEnding);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment