Merge remote-tracking branch 'origin/develop' into
[jalview.git] / src / jalview / structure / StructureSelectionManager.java
index 2dbe360..eb9abab 100644 (file)
@@ -43,6 +43,7 @@ import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
 
@@ -61,7 +62,16 @@ public class StructureSelectionManager
 
   private boolean addTempFacAnnot = false;
 
-  private Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<AlignedCodonFrame>();
+  /*
+   * Set of any registered mappings between (dataset) sequences.
+   */
+  Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<AlignedCodonFrame>();
+
+  /*
+   * Reference counters for the above mappings. Remove mappings when ref count
+   * goes to zero.
+   */
+  Map<AlignedCodonFrame, Integer> seqMappingRefCounts = new HashMap<AlignedCodonFrame, Integer>();
 
   private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
 
@@ -835,7 +845,8 @@ public class StructureSelectionManager
   }
 
   /**
-   * Remove each of the given codonFrames from the stored set (if present).
+   * Decrement the reference counter for each of the given mappings, and remove
+   * it entirely if its reference counter reduces to zero.
    * 
    * @param set
    */
@@ -843,13 +854,40 @@ public class StructureSelectionManager
   {
     if (set != null)
     {
-      seqmappings.removeAll(set);
+      for (AlignedCodonFrame acf : set)
+      {
+        removeMapping(acf);
+      }
     }
   }
 
   /**
-   * Add each of the given codonFrames to the stored set (if not aready
-   * present).
+   * Decrement the reference counter for the given mapping, and remove it
+   * entirely if its reference counter reduces to zero.
+   * 
+   * @param acf
+   */
+  public void removeMapping(AlignedCodonFrame acf)
+  {
+    if (acf != null && seqmappings.contains(acf))
+    {
+      int count = seqMappingRefCounts.get(acf);
+      count--;
+      if (count > 0)
+      {
+        seqMappingRefCounts.put(acf, count);
+      }
+      else
+      {
+        seqmappings.remove(acf);
+        seqMappingRefCounts.remove(acf);
+      }
+    }
+  }
+
+  /**
+   * Add each of the given codonFrames to the stored set. If not aready present,
+   * increments its reference count instead.
    * 
    * @param set
    */
@@ -857,15 +895,30 @@ public class StructureSelectionManager
   {
     if (set != null)
     {
-      seqmappings.addAll(set);
+      for (AlignedCodonFrame acf : set)
+      {
+        addMapping(acf);
+      }
     }
   }
 
+  /**
+   * Add the given mapping to the stored set, or if already stored, increment
+   * its reference counter.
+   */
   public void addMapping(AlignedCodonFrame acf)
   {
     if (acf != null)
     {
-      seqmappings.add(acf);
+      if (seqmappings.contains(acf))
+      {
+        seqMappingRefCounts.put(acf, seqMappingRefCounts.get(acf) + 1);
+      }
+      else
+      {
+        seqmappings.add(acf);
+        seqMappingRefCounts.put(acf, 1);
+      }
     }
   }