From 7b87498751339ed15db058bc0f10e9d3067eaca0 Mon Sep 17 00:00:00 2001 From: Astrash Date: Tue, 7 Feb 2023 11:59:03 +1100 Subject: [PATCH] Don't load same image multiple times --- .../terra/addons/image/ImageLibraryAddon.java | 4 ++- .../addons/image/config/ImageLoader.java | 32 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/ImageLibraryAddon.java b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/ImageLibraryAddon.java index 433606eec..cb556b563 100644 --- a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/ImageLibraryAddon.java +++ b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/ImageLibraryAddon.java @@ -15,6 +15,7 @@ import com.dfsek.terra.addons.image.sampler.ColorSampler; import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.inject.annotations.Inject; @@ -40,7 +41,8 @@ public class ImageLibraryAddon implements AddonInitializer { .register(addon, ConfigPackPreLoadEvent.class) .priority(10) .then(event -> { - event.getPack().applyLoader(Image.class, new ImageLoader(event.getPack().getLoader())); + ConfigPack pack = event.getPack(); + pack.applyLoader(Image.class, new ImageLoader(pack.getLoader(), pack)); }) .then(event -> { CheckedRegistry>> colorSamplerRegistry = event.getPack().getOrCreateRegistry( diff --git a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/config/ImageLoader.java b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/config/ImageLoader.java index 15cbe4c52..cedfbb3bb 100644 --- a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/config/ImageLoader.java +++ b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/config/ImageLoader.java @@ -11,10 +11,13 @@ import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.io.IOException; import java.lang.reflect.AnnotatedType; +import java.util.concurrent.ConcurrentHashMap; import com.dfsek.terra.addons.image.image.BufferedImageWrapper; import com.dfsek.terra.addons.image.image.Image; +import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.Loader; +import com.dfsek.terra.api.properties.Properties; public class ImageLoader implements TypeLoader { @@ -23,19 +26,32 @@ public class ImageLoader implements TypeLoader { private final Loader files; - public ImageLoader(Loader files) { + private final ConfigPack pack; + + public ImageLoader(Loader files, ConfigPack pack) { this.files = files; + this.pack = pack; + if(!pack.getContext().has(ImageCache.class)) + pack.getContext().put(new ImageCache(new ConcurrentHashMap<>())); } @Override public Image load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException { - try { - return new BufferedImageWrapper(ImageIO.read(files.get((String) c))); - } catch(IllegalArgumentException e) { - throw new LoadException("Unable to load image (image might be too large?)", e, depthTracker); - } catch(IOException e) { - throw new LoadException("Unable to load image", e, depthTracker); - } + return pack.getContext().get(ImageCache.class).map.computeIfAbsent((String) c, imagePath -> { + try { + return new BufferedImageWrapper(ImageIO.read(files.get(imagePath))); + } catch(IllegalArgumentException e) { + throw new LoadException("Unable to load image (image might be too large?)", e, depthTracker); + } catch(IOException e) { + throw new LoadException("Unable to load image", e, depthTracker); + } + }); + } + + /* + * Cache prevents configs from loading the same image multiple times into memory + */ + private record ImageCache(ConcurrentHashMap map) implements Properties { } }