From e59bfb8a1f96549bf2b35d782c1b3f6edbcf91ec Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 15 Mar 2023 19:32:12 +0800 Subject: [PATCH 1/2] revert AudioClip, refactor Texture get --- .../src/forge/adventure/util/Config.java | 6 ++-- .../src/forge/adventure/util/Controls.java | 19 +++--------- .../src/forge/adventure/util/RewardActor.java | 30 +++++++++++-------- forge-gui-mobile/src/forge/assets/Assets.java | 7 +++++ .../src/forge/assets/FSkinFont.java | 8 +++-- .../src/forge/assets/ImageCache.java | 6 ++-- .../src/forge/sound/AudioClip.java | 9 +++--- 7 files changed, 45 insertions(+), 40 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/util/Config.java b/forge-gui-mobile/src/forge/adventure/util/Config.java index 0fc0dc9b122..852a2553a85 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Config.java +++ b/forge-gui-mobile/src/forge/adventure/util/Config.java @@ -217,11 +217,13 @@ public class Config { public TextureAtlas getAtlas(String spriteAtlas) { String fileName = getFile(spriteAtlas).path(); - if (!Forge.getAssets().manager().contains(fileName, TextureAtlas.class)) { + TextureAtlas atlas = Forge.getAssets().manager().get(fileName, TextureAtlas.class, false); + if (atlas == null) { Forge.getAssets().manager().load(fileName, TextureAtlas.class); Forge.getAssets().manager().finishLoadingAsset(fileName); + atlas = Forge.getAssets().manager().get(fileName, TextureAtlas.class, false); } - return Forge.getAssets().manager().get(fileName); + return atlas; } public SettingData getSettingData() { diff --git a/forge-gui-mobile/src/forge/adventure/util/Controls.java b/forge-gui-mobile/src/forge/adventure/util/Controls.java index 47a3c8a279a..be813e19a87 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Controls.java +++ b/forge-gui-mobile/src/forge/adventure/util/Controls.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; @@ -258,23 +257,13 @@ public class Controls { static public Skin getSkin() { FileHandle skinFile = Config.instance().getFile(Paths.SKIN); - if (!Forge.getAssets().manager().contains(skinFile.path(), Skin.class)) { + Skin skin = Forge.getAssets().manager().get(skinFile.path(), Skin.class, false); + if (skin == null) { Forge.getAssets().manager().load(skinFile.path(), Skin.class); Forge.getAssets().manager().finishLoadingAsset(skinFile.path()); - FileHandle atlasFile = skinFile.sibling(skinFile.nameWithoutExtension() + ".atlas"); - Forge.getAssets().manager().load(atlasFile.path(), TextureAtlas.class); - Forge.getAssets().manager().finishLoadingAsset(atlasFile.path()); - /*/font skin will load the LanaPixel.fnt now - FileHandle pixelFont = Config.instance().getFile(Paths.SKIN).sibling("LanaPixel.fnt"); - Forge.getAssets().manager().load(pixelFont.path(), BitmapFont.class); - Forge.getAssets().manager().finishLoadingAsset(pixelFont.path()); - Forge.getAssets().manager().get(skinFile.path(), Skin.class).add("default", Forge.getAssets().manager().get(pixelFont.path(), BitmapFont.class), BitmapFont.class); - Forge.getAssets().manager().get(skinFile.path(), Skin.class).addRegions(Forge.getAssets().manager().get(atlasFile.path(), TextureAtlas.class)); - Forge.getAssets().manager().finishLoadingAsset(skinFile.path()); - */ - + skin = Forge.getAssets().manager().get(skinFile.path(), Skin.class, false); } - return Forge.getAssets().manager().get(skinFile.path(), Skin.class); + return skin; } public static Label newLabel(String name) { diff --git a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java index 54c40b966d1..0f5ddd28524 100644 --- a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java +++ b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java @@ -114,21 +114,22 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb if (StringUtils.isBlank(imageKey)) return; File imageFile = ImageKeys.getImageFile(imageKey); - if (imageFile == null) + if (imageFile == null || !imageFile.exists()) return; - if (!Forge.getAssets().manager().contains(imageFile.getPath())) { + Texture replacement = Forge.getAssets().manager().get(imageFile.getPath(), Texture.class, false); + if (replacement == null) { try { Forge.getAssets().manager().load(imageFile.getPath(), Texture.class, Forge.getAssets().getTextureFilter()); Forge.getAssets().manager().finishLoadingAsset(imageFile.getPath()); - count += 1; + replacement = Forge.getAssets().manager().get(imageFile.getPath(), Texture.class, false); } catch (Exception e) { //e.printStackTrace(); return; } } - Texture replacement = Forge.getAssets().manager().get(imageFile.getPath(), Texture.class, false); if (replacement == null) return; + count += 1; image = replacement; loaded = true; if (toolTipImage != null) { @@ -169,13 +170,14 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb File frontFace = ImageKeys.getImageFile(card.getCardImageKey()); if (frontFace != null) { try { - if (!Forge.getAssets().manager().contains(frontFace.getPath())) { + Texture front = Forge.getAssets().manager().get(frontFace.getPath(), Texture.class, false); + if (front == null) { Forge.getAssets().manager().load(frontFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter()); Forge.getAssets().manager().finishLoadingAsset(frontFace.getPath()); - count += 1; + front = Forge.getAssets().manager().get(frontFace.getPath(), Texture.class, false); } - Texture front = Forge.getAssets().manager().get(frontFace.getPath(), Texture.class, false); if (front != null) { + count += 1; setCardImage(front); } else { loaded = false; @@ -194,13 +196,14 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb File backFace = ImageKeys.getImageFile(cardBack.getCardAltImageKey()); if (backFace != null) { try { - if (!Forge.getAssets().manager().contains(backFace.getPath())) { + Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false); + if (back == null) { Forge.getAssets().manager().load(backFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter()); Forge.getAssets().manager().finishLoadingAsset(backFace.getPath()); - ImageCache.updateSynqCount(backFace, 1); + back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false); } - Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false); if (back != null) { + ImageCache.updateSynqCount(backFace, 1); if (holdTooltip != null) { if (holdTooltip.tooltip_actor.getChildren().size <= 2) { holdTooltip.tooltip_actor.altcImage = new RewardImage(processDrawable(back)); @@ -230,13 +233,14 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb int count = 0; if (lookup != null) { try { - if (!Forge.getAssets().manager().contains(lookup.getPath())) { + Texture replacement = Forge.getAssets().manager().get(lookup.getPath(), Texture.class, false); + if (replacement == null) { Forge.getAssets().manager().load(lookup.getPath(), Texture.class, Forge.getAssets().getTextureFilter()); Forge.getAssets().manager().finishLoadingAsset(lookup.getPath()); - count += 1; + replacement = Forge.getAssets().manager().get(lookup.getPath(), Texture.class, false); } - Texture replacement = Forge.getAssets().manager().get(lookup.getPath(), Texture.class, false); if (replacement != null) { + count += 1; setCardImage(replacement); } else { loaded = false; diff --git a/forge-gui-mobile/src/forge/assets/Assets.java b/forge-gui-mobile/src/forge/assets/Assets.java index db22c8dcbb1..9ab36fa8220 100644 --- a/forge-gui-mobile/src/forge/assets/Assets.java +++ b/forge-gui-mobile/src/forge/assets/Assets.java @@ -22,6 +22,7 @@ import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.ObjectMap; import com.github.tommyettinger.textra.Font; import forge.Forge; +import forge.gui.FThreads; import forge.gui.GuiBase; import forge.localinstance.properties.ForgeConstants; import forge.localinstance.skin.FSkinProp; @@ -564,6 +565,12 @@ public class Assets implements Disposable { } } + @Override + public T finishLoadingAsset(String fileName) { + FThreads.assertExecutedByEdt(true); + return super.finishLoadingAsset(fileName); + } + public float getMemoryInMegabytes() { return (float) currentMemory / 1024f / 1024f; } diff --git a/forge-gui-mobile/src/forge/assets/FSkinFont.java b/forge-gui-mobile/src/forge/assets/FSkinFont.java index 78c5a68df91..0ed4fa3462b 100644 --- a/forge-gui-mobile/src/forge/assets/FSkinFont.java +++ b/forge-gui-mobile/src/forge/assets/FSkinFont.java @@ -412,12 +412,14 @@ public class FSkinFont { if (fontFile != null && fontFile.exists()) { FThreads.invokeInEdtNowOrLater(() -> { //font must be initialized on UI thread try { - if (!Forge.getAssets().manager().contains(fontFile.path(), BitmapFont.class) && fontFile.toString().endsWith(".fnt")) { + font = Forge.getAssets().manager().get(fontFile.path(), BitmapFont.class, false); + if (font == null && fontFile.toString().endsWith(".fnt")) { Forge.getAssets().manager().load(fontFile.path(), BitmapFont.class); Forge.getAssets().manager().finishLoadingAsset(fontFile.path()); + font = Forge.getAssets().manager().get(fontFile.path(), BitmapFont.class, false); } - font = Forge.getAssets().manager().get(fontFile.path(), BitmapFont.class); - found[0] = true; + if (font != null) + found[0] = true; } catch (Exception e) { e.printStackTrace(); found[0] = false; diff --git a/forge-gui-mobile/src/forge/assets/ImageCache.java b/forge-gui-mobile/src/forge/assets/ImageCache.java index aba4c8a9274..c7938552dbb 100644 --- a/forge-gui-mobile/src/forge/assets/ImageCache.java +++ b/forge-gui-mobile/src/forge/assets/ImageCache.java @@ -120,7 +120,7 @@ public class ImageCache { CardRenderer.clearcardArtCache(); //unload all cardsLoaded for (String fileName : cardsLoaded) { - if (Forge.getAssets().manager().contains(fileName)) { + if (Forge.getAssets().manager().get(fileName, Texture.class, false) != null) { Forge.getAssets().manager().unload(fileName); } } @@ -303,7 +303,7 @@ public class ImageCache { String fileName = file.getPath(); //load to assetmanager try { - if (!Forge.getAssets().manager().contains(fileName, Texture.class)) { + if (Forge.getAssets().manager().get(fileName, Texture.class, false) == null) { Forge.getAssets().manager().load(fileName, Texture.class, Forge.getAssets().getTextureFilter()); Forge.getAssets().manager().finishLoadingAsset(fileName); counter += 1; @@ -367,7 +367,7 @@ public class ImageCache { //unload from assetmanager to save RAM try { for (String asset : toUnload) { - if (Forge.getAssets().manager().contains(asset)) { + if (Forge.getAssets().manager().get(asset, Texture.class, false) != null) { Forge.getAssets().manager().unload(asset); } cardsLoaded.remove(asset); diff --git a/forge-gui-mobile/src/forge/sound/AudioClip.java b/forge-gui-mobile/src/forge/sound/AudioClip.java index bfff7b00b15..139018f7357 100644 --- a/forge-gui-mobile/src/forge/sound/AudioClip.java +++ b/forge-gui-mobile/src/forge/sound/AudioClip.java @@ -21,7 +21,7 @@ package forge.sound; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.files.FileHandle; -import forge.Forge; +//import forge.Forge; public class AudioClip implements IAudioClip { private Sound clip; @@ -34,7 +34,8 @@ public class AudioClip implements IAudioClip { private AudioClip(final FileHandle fileHandle) { try { - clip = Forge.getAssets().getSound(fileHandle); + //investigate why sound is called outside edt -> Forge.getAssets().getSound(fileHandle), seems the audioclip is cached in SoundSystem instead of using it directly from assetManager + clip = Gdx.audio.newSound(fileHandle); } catch (Exception ex) { System.err.println("Unable to load sound file: " + fileHandle.toString()); @@ -49,7 +50,7 @@ public class AudioClip implements IAudioClip { Thread.sleep(SoundSystem.DELAY); } catch (InterruptedException ex) { - //ex.printStackTrace(); + ex.printStackTrace(); } clip.play(value); } @@ -62,7 +63,7 @@ public class AudioClip implements IAudioClip { Thread.sleep(SoundSystem.DELAY); } catch (InterruptedException ex) { - //ex.printStackTrace(); + ex.printStackTrace(); } clip.loop(); } From 3a849e77ab461a32bbc8f67e488fd9c19b79f6f2 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 15 Mar 2023 22:30:39 +0800 Subject: [PATCH 2/2] add dispose clips --- .../src/main/java/forge/sound/AudioClip.java | 8 ++++++++ .../src/forge/sound/AudioClip.java | 8 ++++++++ .../src/main/java/forge/sound/IAudioClip.java | 1 + .../main/java/forge/sound/NoSoundClip.java | 3 +++ .../main/java/forge/sound/SoundSystem.java | 19 +++++++++++++------ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java index 6438d652d4c..d1579a52c2f 100644 --- a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java +++ b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java @@ -87,6 +87,14 @@ public class AudioClip implements IAudioClip { getIdleClip().loop(); } + @Override + public void dispose() { + for (byte[] b : audioClips.values()) { + b = null; + } + audioClips.clear(); + } + @Override public final void stop() { for (ClipWrapper clip: clips) { diff --git a/forge-gui-mobile/src/forge/sound/AudioClip.java b/forge-gui-mobile/src/forge/sound/AudioClip.java index 139018f7357..2f3aaf81be4 100644 --- a/forge-gui-mobile/src/forge/sound/AudioClip.java +++ b/forge-gui-mobile/src/forge/sound/AudioClip.java @@ -68,6 +68,14 @@ public class AudioClip implements IAudioClip { clip.loop(); } + @Override + public void dispose() { + if (clip != null) { + clip.dispose(); + clip = null; + } + } + public final void stop() { if (clip == null) { return; diff --git a/forge-gui/src/main/java/forge/sound/IAudioClip.java b/forge-gui/src/main/java/forge/sound/IAudioClip.java index a8f1158677d..bd58489b48b 100644 --- a/forge-gui/src/main/java/forge/sound/IAudioClip.java +++ b/forge-gui/src/main/java/forge/sound/IAudioClip.java @@ -5,4 +5,5 @@ public interface IAudioClip { boolean isDone(); void stop(); void loop(); + void dispose(); } diff --git a/forge-gui/src/main/java/forge/sound/NoSoundClip.java b/forge-gui/src/main/java/forge/sound/NoSoundClip.java index 7d519bbb12f..fffca72e5fa 100644 --- a/forge-gui/src/main/java/forge/sound/NoSoundClip.java +++ b/forge-gui/src/main/java/forge/sound/NoSoundClip.java @@ -15,4 +15,7 @@ public class NoSoundClip implements IAudioClip { @Override public void loop() { } + @Override + public void dispose() { } + } diff --git a/forge-gui/src/main/java/forge/sound/SoundSystem.java b/forge-gui/src/main/java/forge/sound/SoundSystem.java index 8d70305a86e..9720da4b113 100644 --- a/forge-gui/src/main/java/forge/sound/SoundSystem.java +++ b/forge-gui/src/main/java/forge/sound/SoundSystem.java @@ -57,9 +57,9 @@ public class SoundSystem { final String resource = type.getResourceFileName(); clip = GuiBase.getInterface().createAudioClip(resource); if (clip == null) { - clip = emptySound; - } - loadedClips.put(type, clip); + return emptySound; + } else + loadedClips.put(type, clip); } return clip; } @@ -85,9 +85,9 @@ public class SoundSystem { if (null == clip) { // cache miss clip = GuiBase.getInterface().createAudioClip(fileName); if (clip == null) { - clip = emptySound; - } - loadedScriptClips.put(fileName, clip); + return emptySound; + } else + loadedScriptClips.put(fileName, clip); } return clip; } @@ -243,6 +243,7 @@ public class SoundSystem { currentTrack.dispose(); currentTrack = null; } + invalidateSoundCache(); } public void fadeModifier(float value) { @@ -288,7 +289,13 @@ public class SoundSystem { } public void invalidateSoundCache() { + for (IAudioClip c : loadedClips.values()) { + c.dispose(); + } loadedClips.clear(); + for (IAudioClip c : loadedScriptClips.values()) { + c.dispose(); + } loadedScriptClips.clear(); }