From b351baa824344763f936dcf30c1bb7f94476f094 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Thu, 13 Jan 2022 15:58:51 -0800 Subject: [PATCH] Handle arbitrary numbers of GameStateProviders - Use bitset instead of long. - We only ever iterate over the GameStateProviders, so use a list instead of a map. - GameStateProviders don't need IDs. --- .../flywheel/core/GameStateRegistry.java | 71 +++++++++---------- .../core/compile/FragmentCompiler.java | 2 +- .../flywheel/core/compile/VertexCompiler.java | 2 +- .../core/shader/GameStateProvider.java | 15 ++-- .../core/shader/NormalDebugStateProvider.java | 18 +---- .../flywheel/core/shader/StateSnapshot.java | 8 ++- 6 files changed, 54 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java b/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java index c8626668e..67a5c2b44 100644 --- a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java @@ -1,61 +1,58 @@ package com.jozufozu.flywheel.core; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; import com.jozufozu.flywheel.core.shader.GameStateProvider; import com.jozufozu.flywheel.core.shader.ShaderConstants; import com.jozufozu.flywheel.core.shader.StateSnapshot; -import net.minecraft.resources.ResourceLocation; - public class GameStateRegistry { - private static final Map registeredStateProviders = new HashMap<>(); + private static final List PROVIDERS = new ArrayList<>(); - public static void _clear() { - registeredStateProviders.clear(); - } - - public static GameStateProvider getStateProvider(ResourceLocation location) { - GameStateProvider out = registeredStateProviders.get(location); - - if (out == null) { - throw new IllegalArgumentException("State provider '" + location + "' does not exist."); - } - - return out; - } - - public static void register(GameStateProvider context) { - if (registeredStateProviders.containsKey(context.getID())) { - throw new IllegalStateException("Duplicate game state provider: " + context.getID()); - } - - registeredStateProviders.put(context.getID(), context); + /** + * Registers a game state provider. + * @param provider The provider to register. + */ + public static void register(GameStateProvider provider) { + PROVIDERS.add(provider); } + /** + * Takes a snapshot of the current game state, storing it in a bit set. + * @return An object that represents the current game state. + */ public static StateSnapshot takeSnapshot() { - long ctx = 0; - for (GameStateProvider state : registeredStateProviders.values()) { - if (state.isTrue()) { - ctx |= 1; + BitSet bitSet = new BitSet(PROVIDERS.size()); + + for (int i = 0, listSize = PROVIDERS.size(); i < listSize; i++) { + if (PROVIDERS.get(i).isTrue()) { + bitSet.set(i); } - ctx <<= 1; } - return new StateSnapshot(ctx); + return new StateSnapshot(bitSet); } - public static ShaderConstants getDefines(long ctx) { - long stateID = ctx; + /** + * Based on the given snapshot, gathers shader constants to be injected during shader compilation. + * @param snapshot The snapshot to use. + * @return A list of shader constants. + */ + public static ShaderConstants getShaderConstants(StateSnapshot snapshot) { + BitSet ctx = snapshot.ctx(); ShaderConstants shaderConstants = new ShaderConstants(); - for (GameStateProvider state : registeredStateProviders.values()) { - if ((stateID & 1) == 1) { - state.alterConstants(shaderConstants); + for (int i = 0, listSize = PROVIDERS.size(); i < listSize; i++) { + if (ctx.get(i)) { + PROVIDERS.get(i).alterConstants(shaderConstants); } - stateID >>= 1; } return shaderConstants; } + + public static void _clear() { + PROVIDERS.clear(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java index 535b688c5..e5600cc66 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java @@ -71,7 +71,7 @@ public class FragmentCompiler extends Memoizer 0) { shaderConstants.define("ALPHA_DISCARD", alphaDiscard); diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/VertexCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/VertexCompiler.java index defec44c5..6487c45c4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/VertexCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/VertexCompiler.java @@ -25,7 +25,7 @@ public class VertexCompiler extends Memoizer { finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.VERTEX)); - key.ctx.getDefines().writeInto(finalSource); + key.ctx.getShaderConstants().writeInto(finalSource); finalSource.append(""" struct Vertex { diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java index 0e9f26bed..2ec67744e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java @@ -1,12 +1,19 @@ package com.jozufozu.flywheel.core.shader; -import net.minecraft.resources.ResourceLocation; - +/** + * An object that provides a view of the current game state for shader compilation. + */ public interface GameStateProvider { - ResourceLocation getID(); - + /** + * Get the status of this game state provider. + * @return Returning {@code true} will cause #alterConstants to be called before compiling a shader. + */ boolean isTrue(); + /** + * Alter the constants for shader compilation. + * @param constants The shader constants. + */ void alterConstants(ShaderConstants constants); } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java index b907d0b0a..50efebd9f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java @@ -1,18 +1,9 @@ package com.jozufozu.flywheel.core.shader; -import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.config.FlwConfig; -import net.minecraft.resources.ResourceLocation; - -public class NormalDebugStateProvider implements GameStateProvider { - - public static final NormalDebugStateProvider INSTANCE = new NormalDebugStateProvider(); - public static final ResourceLocation NAME = Flywheel.rl("normal_debug"); - - protected NormalDebugStateProvider() { - - } +public enum NormalDebugStateProvider implements GameStateProvider { + INSTANCE; @Override public boolean isTrue() { @@ -20,11 +11,6 @@ public class NormalDebugStateProvider implements GameStateProvider { .debugNormals(); } - @Override - public ResourceLocation getID() { - return NAME; - } - @Override public void alterConstants(ShaderConstants constants) { constants.define("DEBUG_NORMAL"); diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java b/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java index b55dd84bb..6a01a90f1 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java @@ -1,11 +1,13 @@ package com.jozufozu.flywheel.core.shader; +import java.util.BitSet; + import com.jozufozu.flywheel.core.GameStateRegistry; -public record StateSnapshot(long ctx) { +public record StateSnapshot(BitSet ctx) { // TODO: is this needed? - public ShaderConstants getDefines() { - return GameStateRegistry.getDefines(ctx); + public ShaderConstants getShaderConstants() { + return GameStateRegistry.getShaderConstants(this); } }