IsmAvatar / LateralGM

A free Game Maker source file editor
http://lateralgm.org/
Other
95 stars 25 forks source link

Sprite Editor Save Error After Editing Subimages #525

Closed RobertBColton closed 4 years ago

RobertBColton commented 4 years ago

Open a sprite with more than one subimage, edit the first subimage, edit the second subimage, save the sprite. You'll get an exception about concurrent modification. This seems to be a regression introduced by 1.8.30 where I had mistakenly removed (https://github.com/IsmAvatar/LateralGM/commit/bcbef27c0bcaf625f09933ba85b9942e4a46ed6f#diff-16887ad9f7a786d5f0f8a08788cf9b96L1847) the array conversion of the editors map which was preventing this exception.

LateralGM Version: 1.8.186
Working Directory: C:\Users\Owner\Documents\Eclipse Workspace\LateralGM\bin

Operating System: Windows 10
Version: 10.0
Architecture: amd64

Java Name: Java HotSpot(TM) 64-Bit Server VM
Java Vendor: Oracle Corporation
Version: 13.0.2

Current Thread: AWT-EventQueue-0
Available processors (cores): 6
Free memory (bytes): 30487648
Maximum memory (bytes): 4259315712
Total memory available to JVM (bytes): 115343360

File system root: C:\
Total space (bytes): 999526756352
Free space (bytes): 603863445504
Usable space (bytes): 603863445504

Stack trace:
java.util.ConcurrentModificationException
    at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1495)
    at java.base/java.util.HashMap$ValueIterator.next(HashMap.java:1523)
    at org.lateralgm.subframes.SpriteFrame.cleanup(SpriteFrame.java:1669)
    at org.lateralgm.subframes.SpriteFrame.dispose(SpriteFrame.java:1662)
    at java.desktop/javax.swing.JInternalFrame.doDefaultCloseAction(JInternalFrame.java:1603)
    at org.lateralgm.components.mdi.RevertableMDIFrame.close(RevertableMDIFrame.java:44)
    at org.lateralgm.subframes.ResourceFrame.doDefaultSaveAction(ResourceFrame.java:227)
    at org.lateralgm.subframes.ResourceFrame.actionPerformed(ResourceFrame.java:234)
    at org.lateralgm.subframes.SpriteFrame.actionPerformed(SpriteFrame.java:1398)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6401)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
RobertBColton commented 4 years ago

Closing as resolved by 2eaf28b64f2e81b6abd16635573c090afa80b8a0 which safely removes the external subimage editors through an iterator during cleanup.