Skip to content

Commit

Permalink
Sprite Frame Close External Editor Concurrent Modification Fix
Browse files Browse the repository at this point in the history
Changes the cleanup loop which stops all of the external subimage
editors to remove the editors using an iterator first. This gets rid of
the concurrent modification exception when you have edited more than
one subimage at the time you save or close the frame. I chose to do it
this way because I didn't want to copy the entire collection. Later the
editors map could possibly be changed to a WeakHashMap which would
automatically remove the keys when the editors are no longer reachable
and eligible for garbage collection. It could also be changed to a
ConcurrentMap which would make it thread safe too.
  • Loading branch information
RobertBColton committed Aug 20, 2020
1 parent 73f0bdf commit 2eaf28b
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
2 changes: 1 addition & 1 deletion org/lateralgm/main/LGM.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@

public final class LGM
{
public static final String version = "1.8.186"; //$NON-NLS-1$
public static final String version = "1.8.187"; //$NON-NLS-1$

// TODO: This list holds the class loader for any loaded plugins which should be
// cleaned up and closed when the application closes.
Expand Down
12 changes: 10 additions & 2 deletions org/lateralgm/subframes/SpriteFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -1666,8 +1667,15 @@ public void dispose()
protected void cleanup()
{
if (editors != null)
for (ImageEditor ie : editors.values())
ie.stop();
// because stopping an editor removes it from the collection we must iterate
// here in a way that prevents concurrent modification exceptions by first
// removing the editor through the iterator so that stop's remove is a noop
for (final Iterator<ImageEditor> it = editors.values().iterator(); it.hasNext();)
{
ImageEditor ie = it.next(); // << grab it first
it.remove(); // << remove it the safe way before stop does
ie.stop(); // << safe from concurrent modification now
}
}

public void lostOwnership(Clipboard arg0, Transferable arg1)
Expand Down

0 comments on commit 2eaf28b

Please sign in to comment.