diff --git a/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java b/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java index 3b109ee..c01c5c6 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java +++ b/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java @@ -2,6 +2,10 @@ package eu.midnightdust.picturesign; import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.util.GIFHandler; +import eu.midnightdust.picturesign.util.MediaHandler; +import eu.midnightdust.picturesign.util.WaterGIFHandler; +import eu.midnightdust.picturesign.util.WaterMediaHandler; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; @@ -21,6 +25,10 @@ public class PictureSignClient { public static void init() { PictureSignConfig.init(MOD_ID, PictureSignConfig.class); + if (hasWaterMedia) { + MediaHandler.registerHandler(WaterMediaHandler::new); + GIFHandler.registerHandler(WaterGIFHandler::new); + } } public static Identifier id(String path) { return Identifier.of(MOD_ID, path); diff --git a/common/src/main/java/eu/midnightdust/picturesign/render/PictureRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/render/PictureRenderer.java index 893c009..7191cae 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/render/PictureRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/render/PictureRenderer.java @@ -38,7 +38,6 @@ import org.joml.Matrix4f; import java.util.Iterator; import static eu.midnightdust.picturesign.PictureSignClient.client; -import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; import static eu.midnightdust.picturesign.PictureSignClient.id; import static eu.midnightdust.picturesign.util.PictureSignType.GIF; import static eu.midnightdust.picturesign.util.PictureSignType.PICTURE; @@ -96,9 +95,9 @@ public class PictureRenderer { MediaHandler mediaHandler = null; GIFHandler gifHandler = null; - if (errorMessage == null && MediaHandler.hasValidImplementation()) { - if (type.isVideo || type.isAudio) mediaHandler = MediaHandler.getOrCreate(videoId, pos); - else if (type == GIF && hasWaterMedia) gifHandler = GIFHandler.getOrCreate(videoId); + if (errorMessage == null) { + if ((type.isVideo || type.isAudio) && MediaHandler.hasValidImplementation()) mediaHandler = MediaHandler.getOrCreate(videoId, pos); + else if (type == GIF && GIFHandler.hasValidImplementation()) gifHandler = GIFHandler.getOrCreate(videoId); else { MediaHandler.closePlayer(videoId); GIFHandler.closePlayer(videoId); @@ -107,8 +106,6 @@ public class PictureRenderer { if (isDisabledViaRedstone(blockEntity.getWorld(), pos)) { if (mediaHandler != null && mediaHandler.isWorking() && !mediaHandler.isStopped()) mediaHandler.stop(); - - //PictureURLUtils.cachedJsonData.remove(url); return; } else if (mediaHandler != null && mediaHandler.isDeactivated) { @@ -126,8 +123,7 @@ public class PictureRenderer { if (!mediaHandler.playbackStarted && !mediaHandler.hasMedia()) { mediaHandler.play(url, type.isVideo); if (info != null && info.start() > 0) mediaHandler.setTime(info.start()); - if (type.isLooped && !mediaHandler.hasMedia() && !mediaHandler.playbackStarted) - mediaHandler.setRepeat(true); + mediaHandler.setRepeat(type.isLooped); } if (info != null && info.volume() >= 0) mediaHandler.setMaxVolume(info.volume()); diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java index 59381ed..611173e 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java @@ -1,64 +1,63 @@ package eu.midnightdust.picturesign.util; -import me.srrapero720.watermedia.api.image.ImageAPI; -import me.srrapero720.watermedia.api.image.ImageCache; -import me.srrapero720.watermedia.api.math.MathAPI; import net.minecraft.util.Identifier; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; - -import static eu.midnightdust.picturesign.PictureSignClient.client; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; public class GIFHandler { - public static Map gifPlayers = new HashMap<>(); + private static final List> implementations = new ArrayList<>(); + public static Map gifHandlers = new HashMap<>(); public final Identifier id; public boolean playbackStarted; - private ImageCache player; - private long tick = 0L; - private GIFHandler(Identifier id) { - System.out.println("New GIF handler :" + id); + public GIFHandler(Identifier id) { this.id = id; - gifPlayers.put(id, this); + gifHandlers.put(id, this); + } + public static void registerHandler(Function handler) { + implementations.add(handler); + } + public static boolean hasValidImplementation() { + return !implementations.isEmpty(); } public static GIFHandler getOrCreate(Identifier id) { - if (gifPlayers.containsKey(id)) return gifPlayers.get(id); - else return new GIFHandler(id); + if (gifHandlers.containsKey(id)) return gifHandlers.get(id); + AtomicReference handler = new AtomicReference<>(); + implementations.forEach(impl -> { + handler.set(impl.apply(id)); + }); + return handler.get(); } public void tick() { - if (player != null && player.getRenderer() != null && tick < player.getRenderer().duration) tick += 1; - else tick = 0; } public void closePlayer() { - player.release(); - player = null; - gifPlayers.remove(this.id); + gifHandlers.remove(this.id); } public static void closePlayer(Identifier videoId) { - if (gifPlayers.containsKey(videoId)) gifPlayers.get(videoId).closePlayer(); + if (gifHandlers.containsKey(videoId)) gifHandlers.get(videoId).closePlayer(); } public static void closeAll() { - gifPlayers.forEach((id, handler) -> handler.closePlayer()); - gifPlayers.clear(); + gifHandlers.forEach((id, handler) -> handler.closePlayer()); + gifHandlers.clear(); } public void play(String url) { - this.player = ImageAPI.getCache(url, client); - player.load(); this.playbackStarted = true; } public boolean hasMedia() { - return player != null && player.getStatus() == ImageCache.Status.READY; + return false; } public int getTexture() { - return player.getRenderer().texture(tick, - (MathAPI.tickToMs(client.getRenderTickCounter().getTickDelta(true))), true); + return -1; } public boolean isWorking() { - if (player != null && player.getException() != null) player.getException().fillInStackTrace(); - return player != null && player.getStatus() == ImageCache.Status.READY && player.getRenderer() != null; + return false; } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java index 38c1977..0beda94 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java @@ -4,14 +4,19 @@ import eu.midnightdust.picturesign.config.PictureSignConfig; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.ApiStatus; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; import static eu.midnightdust.picturesign.PictureSignClient.client; -import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; public abstract class MediaHandler { + private static final List> implementations = new ArrayList<>(); public static Map mediaHandlers = new HashMap<>(); public final Identifier id; @@ -20,19 +25,23 @@ public abstract class MediaHandler { public boolean isDeactivated; int maxVolume = 100; - MediaHandler(Identifier id, BlockPos pos) { + public MediaHandler(Identifier id, BlockPos pos) { this.id = id; this.pos = pos; } + public static void registerHandler(BiFunction handler) { + implementations.add(handler); + } + public static boolean hasValidImplementation() { + return !implementations.isEmpty(); + } public static MediaHandler getOrCreate(Identifier id, BlockPos pos) { if (mediaHandlers.containsKey(id)) return mediaHandlers.get(id); - else if (hasWaterMedia) return new WaterMediaHandler(id, pos); - // Add new implementations here via Mixin - else return null; - } - public static boolean hasValidImplementation() { // Mixin here to add new Multimedia implementations - if (hasWaterMedia) return true; - else return false; + AtomicReference handler = new AtomicReference<>(); + implementations.forEach(impl -> { + handler.set(impl.apply(id, pos)); + }); + return handler.get(); } public void setVolumeBasedOnDistance() { if (!isWorking() || client.player == null) return; @@ -45,7 +54,9 @@ public abstract class MediaHandler { double distance = this.pos.getSquaredDistance(playerPos) / PictureSignConfig.audioDistanceMultiplier; setVolume((int) Math.clamp(maxVolume-distance, 0, 100)); } - void setVolume(int volume) {} + @ApiStatus.Internal + public void setVolume(int volume) {} // Please use 'setMaxVolume' to adjust the playback volume + public void setMaxVolume(int volume) { maxVolume = volume; } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/WaterGIFHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/WaterGIFHandler.java new file mode 100644 index 0000000..b28be5e --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/util/WaterGIFHandler.java @@ -0,0 +1,50 @@ +package eu.midnightdust.picturesign.util; + +import me.srrapero720.watermedia.api.image.ImageAPI; +import me.srrapero720.watermedia.api.image.ImageCache; +import me.srrapero720.watermedia.api.math.MathAPI; +import net.minecraft.util.Identifier; + +import static eu.midnightdust.picturesign.PictureSignClient.client; + +public class WaterGIFHandler extends GIFHandler { + private ImageCache player; + private long tick = 0L; + + public WaterGIFHandler(Identifier id) { + super(id); + } + @Override + public void tick() { + if (player != null && player.getRenderer() != null && tick < player.getRenderer().duration) tick += 1; + else tick = 0; + } + + @Override + public void closePlayer() { + player.release(); + player = null; + super.closePlayer(); + } + + @Override + public void play(String url) { + this.player = ImageAPI.getCache(url, client); + player.load(); + super.play(url); + } + @Override + public boolean hasMedia() { + return player != null && player.getStatus() == ImageCache.Status.READY; + } + @Override + public int getTexture() { + return player.getRenderer().texture(tick, + (MathAPI.tickToMs(client.getRenderTickCounter().getTickDelta(true))), true); + } + @Override + public boolean isWorking() { + if (player != null && player.getException() != null) player.getException().fillInStackTrace(); + return player != null && player.getStatus() == ImageCache.Status.READY && player.getRenderer() != null; + } +} diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java index b939ad4..b90321f 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java @@ -15,12 +15,12 @@ import static eu.midnightdust.picturesign.PictureSignClient.client; public class WaterMediaHandler extends MediaHandler { private SyncBasePlayer player; - WaterMediaHandler(Identifier id, BlockPos pos) { + public WaterMediaHandler(Identifier id, BlockPos pos) { super(id, pos); mediaHandlers.put(id, this); } @Override - void setVolume(int volume) { + public void setVolume(int volume) { player.setVolume((int) (volume * MinecraftClient.getInstance().options.getSoundVolume(SoundCategory.MASTER))); } @@ -36,7 +36,7 @@ public class WaterMediaHandler extends MediaHandler { @Override public void stop() { player.stop(); - isDeactivated = true; + super.stop(); } @Override public boolean isStopped() { diff --git a/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java index 7de7315..0b9df1d 100755 --- a/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java +++ b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java @@ -36,7 +36,7 @@ public class PictureSignClientFabric implements ClientModInitializer { } }); ClientTickEvents.END_CLIENT_TICK.register(client -> { - GIFHandler.gifPlayers.forEach(((identifier, handler) -> handler.tick())); + GIFHandler.gifHandlers.forEach(((identifier, handler) -> handler.tick())); if (!BINDING_COPY_SIGN.isPressed()) return; BINDING_COPY_SIGN.setPressed(false); if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return; diff --git a/gradle.properties b/gradle.properties index 062b8ba..f9c3278 100755 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ yarn_mappings=1.21+build.2 enabled_platforms=fabric,neoforge archives_base_name=picturesign -mod_version=2.0.0 +mod_version=2.0.1 maven_group=eu.midnightdust release_type=release curseforge_id=533897