From 8ad468dbc960c43ee9189e95ddf6737da64ec5bc Mon Sep 17 00:00:00 2001 From: asvitkine Date: Tue, 18 Jul 2023 23:52:00 -0400 Subject: [PATCH] Fix fighter images not switching to jets on tech. (#11794) Adds a TECH_ATTACHMENT_CHANGED event that the UI listens for to invalidate the image cache. Also, adds code to delete colorized temp files on game end as well as cleaning up some tech results display code. --- .../strategy/engine/data/GameDataEvent.java | 10 +++++++++- .../triplea/image/UnitImageFactory.java | 16 ++++++++++++++++ .../triplea/ui/TechResultsDisplay.java | 18 +++++------------- .../games/strategy/triplea/ui/UiContext.java | 1 + .../strategy/triplea/ui/TripleAFrame.java | 9 ++++++++- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java b/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java index 757d2d07e5b..b6dae5bc959 100644 --- a/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java +++ b/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java @@ -1,12 +1,14 @@ package games.strategy.engine.data; import games.strategy.engine.data.changefactory.ObjectPropertyChange; +import games.strategy.triplea.Constants; import java.util.Optional; /** Enum that represents various possible game data change events. */ public enum GameDataEvent { UNIT_MOVED, - GAME_STEP_CHANGED; + GAME_STEP_CHANGED, + TECH_ATTACHMENT_CHANGED; /** * Converts a 'Change' object to a 'GameDataEvent' object, returns empty if the change object does @@ -16,6 +18,12 @@ static Optional lookupEvent(final Change change) { if (hasMoveChange(change)) { return Optional.of(UNIT_MOVED); } + if (change instanceof ChangeAttachmentChange) { + ChangeAttachmentChange attachmentChange = (ChangeAttachmentChange) change; + if (attachmentChange.getAttachmentName().equals(Constants.TECH_ATTACHMENT_NAME)) { + return Optional.of(TECH_ATTACHMENT_CHANGED); + } + } return Optional.empty(); } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java b/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java index ef606427d4b..3e3920b5fad 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java @@ -25,7 +25,9 @@ import java.io.IOException; import java.net.URL; import java.nio.file.Files; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import javax.imageio.ImageIO; @@ -60,6 +62,7 @@ public class UnitImageFactory { private final Map icons = new HashMap<>(); // Temporary colorized image files used for URLs for html views (e.g. unit stats table). private final Map colorizedTempFiles = new HashMap<>(); + private final List tempFiles = new ArrayList<>(); // Scaling factor for unit images private final double scaleFactor; private final ResourceLoader resourceLoader; @@ -76,6 +79,18 @@ public UnitImageFactory( this.mapData = mapData; } + public void clearCache() { + images.clear(); + icons.clear(); + deleteTempFiles(); + colorizedTempFiles.clear(); + } + + public void deleteTempFiles() { + tempFiles.forEach(File::delete); + tempFiles.clear(); + } + @Value @Builder public static class ImageKey { @@ -283,6 +298,7 @@ public Optional getPossiblyTransformedImageUrl(final ImageKey imageKey) { File file = Files.createTempFile(key.getFullName(), ".png").toFile(); // Delete the file on exit. file.deleteOnExit(); + tempFiles.add(file); ImageIO.write(bufferedImage, "PNG", file); return file.toURI().toURL(); } catch (IOException e) { diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java b/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java index c9058641787..82ccbcf0920 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java @@ -69,25 +69,17 @@ class TechResultsDisplay extends JPanel { final JPanel dice = new JPanel(); dice.setLayout(new BoxLayout(dice, BoxLayout.X_AXIS)); final int remainder = msg.getRemainder(); + final var diceFactory = uiContext.getDiceImageFactory(); for (int i = 0; i < msg.getRolls().length; i++) { // add 1 since dice are 0 based final int roll = msg.getRolls()[i] + 1; - final JLabel die; + final Die.DieType dieType; if (remainder > 0) { - die = - new JLabel( - uiContext - .getDiceImageFactory() - .getDieIcon(roll, roll <= remainder ? Die.DieType.HIT : Die.DieType.MISS)); + dieType = (roll <= remainder) ? Die.DieType.HIT : Die.DieType.MISS; } else { - die = - new JLabel( - uiContext - .getDiceImageFactory() - .getDieIcon( - roll, roll == data.getDiceSides() ? Die.DieType.HIT : Die.DieType.MISS)); + dieType = (roll == data.getDiceSides()) ? Die.DieType.HIT : Die.DieType.MISS; } - dice.add(die); + dice.add(new JLabel(diceFactory.getDieIcon(roll, dieType))); dice.add(Box.createHorizontalStrut(2)); dice.setMaximumSize(new Dimension(200, (int) dice.getMaximumSize().getHeight())); } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java b/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java index ee59cbf0deb..e6804c19691 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java @@ -179,6 +179,7 @@ public void shutDown() { } activeToDeactivate.clear(); windowsToCloseOnShutdown.clear(); + unitImageFactory.deleteTempFiles(); } StackTraceReportModel.setCurrentMapName(null); resourceLoader.close(); diff --git a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java index f90935578b4..489ba97369d 100644 --- a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java +++ b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java @@ -441,10 +441,17 @@ protected void paintComponent(final Graphics g) { // force a data change event to update the UI for edit mode dataChangeListener.gameDataChanged(ChangeFactory.EMPTY_CHANGE); data.addDataChangeListener(dataChangeListener); - game.getData().addGameDataEventListener(GameDataEvent.GAME_STEP_CHANGED, this::updateStep); + data.addGameDataEventListener(GameDataEvent.GAME_STEP_CHANGED, this::updateStep); + // Clear cached unit images when getting standard tech like jet power. + data.addGameDataEventListener( + GameDataEvent.TECH_ATTACHMENT_CHANGED, this::clearCachedUnitImages); uiContext.addShutdownWindow(this); } + private void clearCachedUnitImages() { + uiContext.getUnitImageFactory().clearCache(); + } + /** * Constructs a new instance of a TripleAFrame, but executes required IO-Operations off the EDT. */