diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 0040cdc16..864f616db 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -152,7 +152,7 @@ public class Flywheel { info.add(""); info.add("Flywheel: " + getVersion()); info.add("Backend: " + BackendManagerImpl.getBackendString()); - info.add("Update limiting: " + FlwCommands.boolToText(FlwConfig.get().limitUpdates()).getString()); + info.add("Update limiting: " + (FlwConfig.get().limitUpdates() ? "on" : "off")); VisualizationManager manager = VisualizationManager.get(mc.level); if (manager != null) { diff --git a/src/main/java/com/jozufozu/flywheel/api/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/api/backend/Backend.java index 31dce2dce..0d229152e 100644 --- a/src/main/java/com/jozufozu/flywheel/api/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/api/backend/Backend.java @@ -4,18 +4,12 @@ import com.jozufozu.flywheel.api.BackendImplemented; import com.jozufozu.flywheel.api.internal.InternalFlywheelApi; import com.jozufozu.flywheel.api.registry.IdRegistry; -import net.minecraft.network.chat.Component; import net.minecraft.world.level.LevelAccessor; @BackendImplemented public interface Backend { static IdRegistry REGISTRY = InternalFlywheelApi.INSTANCE.createIdRegistry(); - /** - * Get a message to display to the user when the engine is enabled. - */ - Component engineMessage(); - /** * Create a new engine instance. */ diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index ada863bb0..132782e66 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -1,6 +1,5 @@ package com.jozufozu.flywheel.backend; - import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.backend.Backend; import com.jozufozu.flywheel.backend.compile.IndirectPrograms; @@ -11,16 +10,11 @@ import com.jozufozu.flywheel.backend.gl.GlCompat; import com.jozufozu.flywheel.lib.backend.SimpleBackend; import com.jozufozu.flywheel.lib.util.ShadersModHandler; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; - -public class Backends { +public final class Backends { /** * Use GPU instancing to render everything. */ public static final Backend INSTANCING = SimpleBackend.builder() - .engineMessage(Component.literal("Using Instancing Engine") - .withStyle(ChatFormatting.GREEN)) .engineFactory(level -> new InstancingEngine(InstancingPrograms.get(), 256)) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsInstancing() && InstancingPrograms.allLoaded()) .register(Flywheel.rl("instancing")); @@ -29,13 +23,14 @@ public class Backends { * Use Compute shaders to cull instances. */ public static final Backend INDIRECT = SimpleBackend.builder() - .engineMessage(Component.literal("Using Indirect Engine") - .withStyle(ChatFormatting.GREEN)) .engineFactory(level -> new IndirectEngine(IndirectPrograms.get(), 256)) .fallback(() -> Backends.INSTANCING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsIndirect() && IndirectPrograms.allLoaded()) .register(Flywheel.rl("indirect")); + private Backends() { + } + public static void init() { } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/Samplers.java b/src/main/java/com/jozufozu/flywheel/backend/Samplers.java similarity index 89% rename from src/main/java/com/jozufozu/flywheel/backend/engine/Samplers.java rename to src/main/java/com/jozufozu/flywheel/backend/Samplers.java index d3ac03c80..f77dd99dd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/Samplers.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Samplers.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.engine; +package com.jozufozu.flywheel.backend; import com.jozufozu.flywheel.backend.gl.GlTextureUnit; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/ContextShaders.java b/src/main/java/com/jozufozu/flywheel/backend/compile/ContextShaders.java index 695f73c36..37cce6b74 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/ContextShaders.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/ContextShaders.java @@ -6,7 +6,7 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.internal.InternalFlywheelApi; import com.jozufozu.flywheel.api.registry.Registry; import com.jozufozu.flywheel.api.visualization.VisualEmbedding; -import com.jozufozu.flywheel.backend.engine.Samplers; +import com.jozufozu.flywheel.backend.Samplers; public class ContextShaders { public static final Registry REGISTRY = InternalFlywheelApi.INSTANCE.createRegistry(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java index 7ebb62814..40e6218c2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -17,11 +17,12 @@ import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.glsl.GlslVersion; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; +import com.jozufozu.flywheel.backend.util.AtomicReferenceCounted; import com.jozufozu.flywheel.lib.util.ResourceUtil; import net.minecraft.resources.ResourceLocation; -public class IndirectPrograms extends AbstractPrograms { +public class IndirectPrograms extends AtomicReferenceCounted { private static final ResourceLocation CULL_SHADER_HEADER = Flywheel.rl("internal/indirect/cull_header.glsl"); private static final ResourceLocation CULL_SHADER_MAIN = Flywheel.rl("internal/indirect/cull.glsl"); private static final ResourceLocation APPLY_SHADER_MAIN = Flywheel.rl("internal/indirect/apply.glsl"); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java index ffbbe8f14..ee4924656 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java @@ -10,8 +10,9 @@ import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; +import com.jozufozu.flywheel.backend.util.AtomicReferenceCounted; -public class InstancingPrograms extends AbstractPrograms { +public class InstancingPrograms extends AtomicReferenceCounted { @Nullable private static InstancingPrograms instance; @@ -24,7 +25,7 @@ public class InstancingPrograms extends AbstractPrograms { static void reload(ShaderSources sources, ImmutableList pipelineKeys, List vertexComponents, List fragmentComponents) { InstancingPrograms newInstance = null; - var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, vertexComponents, fragmentComponents); + var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCING, vertexComponents, fragmentComponents); try { var pipelineResult = pipelineCompiler.compileAndReportErrors(pipelineKeys); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java index 3d544cd5b..dd9589535 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java @@ -3,9 +3,9 @@ package com.jozufozu.flywheel.backend.compile; import java.util.List; import com.jozufozu.flywheel.backend.InternalVertex; +import com.jozufozu.flywheel.backend.Samplers; import com.jozufozu.flywheel.backend.compile.core.CompilationHarness; import com.jozufozu.flywheel.backend.compile.core.Compile; -import com.jozufozu.flywheel.backend.engine.Samplers; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.glsl.ShaderSources; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java index 061e2234e..ff4718722 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java @@ -1,13 +1,13 @@ package com.jozufozu.flywheel.backend.compile; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.backend.Samplers; import com.jozufozu.flywheel.backend.compile.component.IndirectComponent; import com.jozufozu.flywheel.backend.compile.component.SamplerBufferComponent; -import com.jozufozu.flywheel.backend.engine.Samplers; import com.jozufozu.flywheel.backend.glsl.GlslVersion; public final class Pipelines { - public static final Pipeline INSTANCED_ARRAYS = Pipeline.builder() + public static final Pipeline INSTANCING = Pipeline.builder() .compilerMarker("instancing") .glslVersion(GlslVersion.V330) .vertexMain(Flywheel.rl("internal/instancing/main.vert")) diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialRenderState.java b/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialRenderState.java index 9d5821ecf..961863221 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialRenderState.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialRenderState.java @@ -8,6 +8,7 @@ import com.jozufozu.flywheel.api.material.DepthTest; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.Transparency; import com.jozufozu.flywheel.api.material.WriteMask; +import com.jozufozu.flywheel.backend.Samplers; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/MeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/engine/MeshPool.java index acff38427..9c0b9768b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/MeshPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/MeshPool.java @@ -14,6 +14,7 @@ import com.jozufozu.flywheel.backend.InternalVertex; import com.jozufozu.flywheel.backend.gl.GlPrimitive; import com.jozufozu.flywheel.backend.gl.array.GlVertexArray; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.util.ReferenceCounted; import com.jozufozu.flywheel.lib.memory.MemoryBlock; public class MeshPool { @@ -93,7 +94,7 @@ public class MeshPool { private void processDeletions() { // remove deleted meshes meshList.removeIf(pooledMesh -> { - boolean deleted = pooledMesh.deleted(); + boolean deleted = pooledMesh.isDeleted(); if (deleted) { meshes.remove(pooledMesh.mesh); } @@ -141,14 +142,12 @@ public class MeshPool { meshList.clear(); } - public class PooledMesh { + public class PooledMesh extends ReferenceCounted { public static final int INVALID_BASE_VERTEX = -1; + private final Mesh mesh; - private int baseVertex = INVALID_BASE_VERTEX; - private int referenceCount = 0; - private PooledMesh(Mesh mesh) { this.mesh = mesh; } @@ -177,12 +176,8 @@ public class MeshPool { return (long) firstIndex() * Integer.BYTES; } - public boolean deleted() { - return referenceCount <= 0; - } - - public boolean invalid() { - return mesh.vertexCount() == 0 || baseVertex == INVALID_BASE_VERTEX || deleted(); + public boolean isInvalid() { + return mesh.vertexCount() == 0 || baseVertex == INVALID_BASE_VERTEX || isDeleted(); } public void draw(int instanceCount) { @@ -193,15 +188,10 @@ public class MeshPool { } } - public void acquire() { - referenceCount++; - } - - public void release() { - if (--referenceCount == 0) { - MeshPool.this.dirty = true; - MeshPool.this.anyToRemove = true; - } + @Override + protected void delete() { + MeshPool.this.dirty = true; + MeshPool.this.anyToRemove = true; } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/TextureBinder.java b/src/main/java/com/jozufozu/flywheel/backend/engine/TextureBinder.java index 7a80daf6c..7751d94ce 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/TextureBinder.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/TextureBinder.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.engine; +import com.jozufozu.flywheel.backend.Samplers; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java index 5d08a189e..8faec98da 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -182,8 +182,8 @@ public class IndirectCullingGroup { instancers.add(instancer); for (var entry : model.meshes()) { - MeshPool.PooledMesh pooledMesh = meshPool.alloc(entry.mesh()); - var draw = new IndirectDraw(instancer, entry.material(), pooledMesh, stage); + MeshPool.PooledMesh mesh = meshPool.alloc(entry.mesh()); + var draw = new IndirectDraw(instancer, entry.material(), mesh, stage); indirectDraws.add(draw); instancer.addDraw(draw); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java index c507ef39e..2f5861647 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -15,6 +15,7 @@ import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.backend.Samplers; import com.jozufozu.flywheel.backend.compile.ContextShaders; import com.jozufozu.flywheel.backend.compile.IndirectPrograms; import com.jozufozu.flywheel.backend.engine.CommonCrumbling; @@ -24,7 +25,6 @@ import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.jozufozu.flywheel.backend.engine.InstancerStorage; import com.jozufozu.flywheel.backend.engine.MaterialRenderState; import com.jozufozu.flywheel.backend.engine.MeshPool; -import com.jozufozu.flywheel.backend.engine.Samplers; import com.jozufozu.flywheel.backend.engine.TextureBinder; import com.jozufozu.flywheel.backend.engine.uniform.Uniforms; import com.jozufozu.flywheel.backend.gl.GlStateTracker; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java index 4471f5b85..0cafc89db 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java @@ -24,7 +24,7 @@ public class DrawCall { } public void render(TextureBuffer buffer) { - if (mesh.invalid()) { + if (mesh.isInvalid()) { return; } @@ -34,7 +34,7 @@ public class DrawCall { } public void renderOne(TextureBuffer buffer, InstanceHandleImpl impl) { - if (mesh.invalid()) { + if (mesh.isInvalid()) { return; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java index 3f0192921..04b640ecc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java @@ -18,6 +18,7 @@ import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.backend.Samplers; import com.jozufozu.flywheel.backend.ShaderIndices; import com.jozufozu.flywheel.backend.compile.ContextShaders; import com.jozufozu.flywheel.backend.compile.InstancingPrograms; @@ -28,7 +29,6 @@ import com.jozufozu.flywheel.backend.engine.InstancerStorage; import com.jozufozu.flywheel.backend.engine.MaterialEncoder; import com.jozufozu.flywheel.backend.engine.MaterialRenderState; import com.jozufozu.flywheel.backend.engine.MeshPool; -import com.jozufozu.flywheel.backend.engine.Samplers; import com.jozufozu.flywheel.backend.engine.TextureBinder; import com.jozufozu.flywheel.backend.engine.uniform.Uniforms; import com.jozufozu.flywheel.backend.gl.GlStateTracker; diff --git a/src/main/java/com/jozufozu/flywheel/backend/util/AtomicReferenceCounted.java b/src/main/java/com/jozufozu/flywheel/backend/util/AtomicReferenceCounted.java new file mode 100644 index 000000000..cf45d7a5d --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/util/AtomicReferenceCounted.java @@ -0,0 +1,40 @@ +package com.jozufozu.flywheel.backend.util; + +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class AtomicReferenceCounted { + private final AtomicInteger referenceCount = new AtomicInteger(0); + private volatile boolean isDeleted = false; + + public int referenceCount() { + return referenceCount.get(); + } + + public boolean isDeleted() { + return isDeleted; + } + + public void acquire() { + if (isDeleted) { + throw new IllegalStateException("Tried to acquire deleted instance of '" + getClass().getName() + "'!"); + } + + referenceCount.getAndIncrement(); + } + + public void release() { + if (isDeleted) { + throw new IllegalStateException("Tried to release deleted instance of '" + getClass().getName() + "'!"); + } + + int newCount = referenceCount.decrementAndGet(); + if (newCount == 0) { + isDeleted = true; + delete(); + } else if (newCount < 0) { + throw new IllegalStateException("Tried to delete instance of '" + getClass().getName() + "' more times than it was acquired!"); + } + } + + protected abstract void delete(); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/util/ReferenceCounted.java similarity index 50% rename from src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java rename to src/main/java/com/jozufozu/flywheel/backend/util/ReferenceCounted.java index d3acb56b1..ee3cf0786 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/util/ReferenceCounted.java @@ -1,24 +1,31 @@ -package com.jozufozu.flywheel.backend.compile; +package com.jozufozu.flywheel.backend.util; -import java.util.concurrent.atomic.AtomicInteger; +public abstract class ReferenceCounted { + private int referenceCount = 0; + private boolean isDeleted = false; -public abstract class AbstractPrograms { - private final AtomicInteger refCount = new AtomicInteger(); - private volatile boolean isDeleted; + public int referenceCount() { + return referenceCount; + } - public int refCount() { - return refCount.get(); + public boolean isDeleted() { + return isDeleted; } public void acquire() { if (isDeleted) { throw new IllegalStateException("Tried to acquire deleted instance of '" + getClass().getName() + "'!"); } - refCount.getAndIncrement(); + + referenceCount++; } public void release() { - int newCount = refCount.decrementAndGet(); + if (isDeleted) { + throw new IllegalStateException("Tried to release deleted instance of '" + getClass().getName() + "'!"); + } + + int newCount = --referenceCount; if (newCount == 0) { isDeleted = true; delete(); diff --git a/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java b/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java index 93ee2da72..0793a6bb5 100644 --- a/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java +++ b/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java @@ -23,7 +23,7 @@ public class BackendArgument implements ArgumentType { private static final List EXAMPLES = List.of("off", "flywheel:off", "instancing"); private static final DynamicCommandExceptionType ERROR_UNKNOWN_BACKEND = new DynamicCommandExceptionType(arg -> { - return Component.literal("Unknown backend '" + arg + "'"); + return Component.translatable("argument.flywheel_backend.id.unknown", arg); }); public static final BackendArgument INSTANCE = new BackendArgument(); diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index 5301ce4a0..6fdfbae1f 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -9,94 +9,70 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import net.minecraft.ChatFormatting; -import net.minecraft.ResourceLocationException; import net.minecraft.client.Minecraft; -import net.minecraft.client.player.LocalPlayer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraftforge.client.event.RegisterClientCommandsEvent; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; import net.minecraftforge.server.command.EnumArgument; -public class FlwCommands { +public final class FlwCommands { + private FlwCommands() { + } + public static void registerClientCommands(RegisterClientCommandsEvent event) { FlwConfig config = FlwConfig.get(); LiteralArgumentBuilder command = Commands.literal("flywheel"); - addValue(command, config.client.backend, "backend", (builder, value) -> - builder + ConfigValue backendValue = config.client.backend; + command.then(Commands.literal("backend") .executes(context -> { - LocalPlayer player = Minecraft.getInstance().player; - if (player != null) { - String backendIdStr = value.get(); - - ResourceLocation backendId; - try { - backendId = new ResourceLocation(backendIdStr); - } catch (ResourceLocationException e) { - player.displayClientMessage(Component.literal("Config contains invalid backend ID '" + backendIdStr + "'!"), false); - return 0; - } - - Backend backend = Backend.REGISTRY.get(backendId); - if (backend == null) { - player.displayClientMessage(Component.literal("Config contains non-existent backend with ID '" + backendId + "'!"), false); - return 0; - } - - Component message = backend.engineMessage(); - player.displayClientMessage(message, false); - } + Backend backend = BackendManager.getBackend(); + String idStr = Backend.REGISTRY.getIdOrThrow(backend) + .toString(); + sendMessage(context.getSource(), Component.translatable("command.flywheel.backend.get", idStr)); return Command.SINGLE_SUCCESS; }) .then(Commands.argument("id", BackendArgument.INSTANCE) .executes(context -> { - LocalPlayer player = Minecraft.getInstance().player; - if (player != null) { - Backend requestedBackend = context.getArgument("id", Backend.class); - var requestedId = Backend.REGISTRY.getIdOrThrow(requestedBackend) - .toString(); - value.set(requestedId); + Backend requestedBackend = context.getArgument("id", Backend.class); + String requestedIdStr = Backend.REGISTRY.getIdOrThrow(requestedBackend) + .toString(); + backendValue.set(requestedIdStr); - // Reload renderers so we can report the backend that we fell back to. - Minecraft.getInstance().levelRenderer.allChanged(); + // Reload renderers so we can report the actual backend. + Minecraft.getInstance().levelRenderer.allChanged(); - var actualBackend = BackendManager.getBackend(); - if (actualBackend != requestedBackend) { - player.displayClientMessage(Component.literal("'" + requestedId + "' not available") - .withStyle(ChatFormatting.RED), false); - } - - Component message = actualBackend.engineMessage(); - player.displayClientMessage(message, false); + Backend actualBackend = BackendManager.getBackend(); + if (actualBackend != requestedBackend) { + sendFailure(context.getSource(), Component.translatable("command.flywheel.backend.set.unavailable", requestedIdStr)); } + + String actualIdStr = Backend.REGISTRY.getIdOrThrow(actualBackend) + .toString(); + sendMessage(context.getSource(), Component.translatable("command.flywheel.backend.set", actualIdStr)); return Command.SINGLE_SUCCESS; }))); - addValue(command, config.client.limitUpdates, "limitUpdates", (builder, value) -> booleanValueCommand(builder, value, + command.then(booleanValueCommand(Commands.literal("limitUpdates"), config.client.limitUpdates, (source, bool) -> { - LocalPlayer player = Minecraft.getInstance().player; - if (player == null) return; - - Component text = Component.literal("Update limiting is currently: ") - .append(boolToText(bool)); - player.displayClientMessage(text, false); + if (bool) { + sendMessage(source, Component.translatable("command.flywheel.limit_updates.get.on")); + } else { + sendMessage(source, Component.translatable("command.flywheel.limit_updates.get.off")); + } }, (source, bool) -> { - LocalPlayer player = Minecraft.getInstance().player; - if (player == null) return; - - Component text = boolToText(bool).append(Component.literal(" update limiting.") - .withStyle(ChatFormatting.WHITE)); - player.displayClientMessage(text, false); + if (bool) { + sendMessage(source, Component.translatable("command.flywheel.limit_updates.set.on")); + } else { + sendMessage(source, Component.translatable("command.flywheel.limit_updates.set.off")); + } Minecraft.getInstance().levelRenderer.allChanged(); } @@ -105,13 +81,21 @@ public class FlwCommands { command.then(Commands.literal("debug") .then(Commands.argument("mode", EnumArgument.enumArgument(DebugMode.class)) .executes(context -> { - LocalPlayer player = Minecraft.getInstance().player; - if (player == null) return 0; - DebugMode mode = context.getArgument("mode", DebugMode.class); - Uniforms.setDebugMode(mode); + return Command.SINGLE_SUCCESS; + }))); + command.then(Commands.literal("frustum") + .then(Commands.literal("unpause") + .executes(context -> { + Uniforms.frustumPaused = false; + return Command.SINGLE_SUCCESS; + })) + .then(Commands.literal("capture") + .executes(context -> { + Uniforms.frustumPaused = true; + Uniforms.frustumCapture = true; return Command.SINGLE_SUCCESS; }))); @@ -119,9 +103,6 @@ public class FlwCommands { .then(Commands.argument("pos", BlockPosArgument.blockPos()) .then(Commands.argument("stage", IntegerArgumentType.integer(0, 9)) .executes(context -> { - BlockPos pos = BlockPosArgument.getBlockPos(context, "pos"); - int value = IntegerArgumentType.getInteger(context, "stage"); - Entity executor = context.getSource() .getEntity(); @@ -129,36 +110,20 @@ public class FlwCommands { return 0; } + BlockPos pos = BlockPosArgument.getBlockPos(context, "pos"); + int value = IntegerArgumentType.getInteger(context, "stage"); + executor.level() .destroyBlockProgress(executor.getId(), pos, value); return Command.SINGLE_SUCCESS; })))); - command.then(Commands.literal("frustum") - .then(Commands.literal("unpause") - .executes(context -> { - Uniforms.frustumPaused = false; - return 1; - })) - .then(Commands.literal("capture") - .executes(context -> { - Uniforms.frustumPaused = true; - Uniforms.frustumCapture = true; - return 1; - }))); - event.getDispatcher().register(command); } - private static > void addValue(LiteralArgumentBuilder command, T value, String subcommand, BiConsumer, T> consumer) { - LiteralArgumentBuilder builder = Commands.literal(subcommand); - consumer.accept(builder, value); - command.then(builder); - } - - private static void booleanValueCommand(LiteralArgumentBuilder builder, ConfigValue value, BiConsumer displayAction, BiConsumer setAction) { - builder + private static LiteralArgumentBuilder booleanValueCommand(LiteralArgumentBuilder builder, ConfigValue value, BiConsumer displayAction, BiConsumer setAction) { + return builder .executes(context -> { displayAction.accept(context.getSource(), value.get()); return Command.SINGLE_SUCCESS; @@ -177,9 +142,11 @@ public class FlwCommands { })); } - public static MutableComponent boolToText(boolean b) { - return b ? Component.literal("enabled") - .withStyle(ChatFormatting.DARK_GREEN) : Component.literal("disabled") - .withStyle(ChatFormatting.RED); + private static void sendMessage(CommandSourceStack source, Component message) { + source.sendSuccess(() -> message, true); + } + + private static void sendFailure(CommandSourceStack source, Component message) { + source.sendFailure(message); } } diff --git a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java index eeb0ac378..513fed7d7 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java @@ -12,9 +12,7 @@ import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl; import com.jozufozu.flywheel.lib.backend.SimpleBackend; import com.mojang.logging.LogUtils; -import net.minecraft.ChatFormatting; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.fml.CrashReportCallables; @@ -22,8 +20,6 @@ public final class BackendManagerImpl { private static final Logger LOGGER = LogUtils.getLogger(); public static final Backend OFF_BACKEND = SimpleBackend.builder() - .engineMessage(Component.literal("Disabled Flywheel") - .withStyle(ChatFormatting.RED)) .engineFactory(level -> { throw new UnsupportedOperationException("Cannot create engine when backend is off."); }) diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManagerImpl.java index 8351eaac0..0c9a2fcd5 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManagerImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManagerImpl.java @@ -70,7 +70,7 @@ public class VisualManagerImpl> implements VisualManager } public Plan tickPlan() { - return SimplePlan.of(context -> processQueue(0)) + return SimplePlan.of(context -> processQueue(1)) .then(storage.tickPlan()); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java b/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java index 4a93b4f71..b2c5a6927 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java +++ b/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java @@ -8,18 +8,15 @@ import com.jozufozu.flywheel.api.backend.Backend; import com.jozufozu.flywheel.api.backend.BackendManager; import com.jozufozu.flywheel.api.backend.Engine; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.LevelAccessor; public class SimpleBackend implements Backend { - private final Component engineMessage; private final Function engineFactory; private final Supplier fallback; private final BooleanSupplier isSupported; - public SimpleBackend(Component engineMessage, Function engineFactory, Supplier fallback, BooleanSupplier isSupported) { - this.engineMessage = engineMessage; + public SimpleBackend(Function engineFactory, Supplier fallback, BooleanSupplier isSupported) { this.engineFactory = engineFactory; this.fallback = fallback; this.isSupported = isSupported; @@ -29,11 +26,6 @@ public class SimpleBackend implements Backend { return new Builder(); } - @Override - public Component engineMessage() { - return engineMessage; - } - @Override public Engine createEngine(LevelAccessor level) { return engineFactory.apply(level); @@ -41,7 +33,7 @@ public class SimpleBackend implements Backend { @Override public Backend findFallback() { - if (this.isSupported()) { + if (isSupported()) { return this; } else { return fallback.get() @@ -55,16 +47,10 @@ public class SimpleBackend implements Backend { } public static class Builder { - private Component engineMessage; private Function engineFactory; private Supplier fallback = BackendManager::getOffBackend; private BooleanSupplier isSupported; - public Builder engineMessage(Component engineMessage) { - this.engineMessage = engineMessage; - return this; - } - public Builder engineFactory(Function engineFactory) { this.engineFactory = engineFactory; return this; @@ -81,7 +67,7 @@ public class SimpleBackend implements Backend { } public Backend register(ResourceLocation id) { - return Backend.REGISTRY.registerAndGet(id, new SimpleBackend(engineMessage, engineFactory, fallback, isSupported)); + return Backend.REGISTRY.registerAndGet(id, new SimpleBackend(engineFactory, fallback, isSupported)); } } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/part/VertexWriter.java b/src/main/java/com/jozufozu/flywheel/lib/model/part/VertexWriter.java index 543b33ae6..b4c908a01 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/model/part/VertexWriter.java +++ b/src/main/java/com/jozufozu/flywheel/lib/model/part/VertexWriter.java @@ -12,7 +12,6 @@ import com.mojang.blaze3d.vertex.VertexConsumer; class VertexWriter implements VertexConsumer { private static final int STRIDE = (int) PosTexNormalVertexView.STRIDE; - private static final int GROWTH_MARGIN = 128 * STRIDE; private MemoryBlock data; @@ -26,7 +25,7 @@ class VertexWriter implements VertexConsumer { private boolean filledNormal; public VertexWriter() { - data = MemoryBlock.malloc(GROWTH_MARGIN); + data = MemoryBlock.malloc(128 * STRIDE); } public void setTextureMapper(@Nullable TextureMapper mapper) { @@ -105,8 +104,9 @@ class VertexWriter implements VertexConsumer { vertexCount++; long byteSize = (vertexCount + 1) * STRIDE; - if (byteSize > data.size()) { - data = data.realloc(byteSize + GROWTH_MARGIN); + long capacity = data.size(); + if (byteSize > capacity) { + data = data.realloc(capacity * 2); } } diff --git a/src/main/resources/assets/flywheel/lang/en_us.json b/src/main/resources/assets/flywheel/lang/en_us.json new file mode 100644 index 000000000..88d3081c4 --- /dev/null +++ b/src/main/resources/assets/flywheel/lang/en_us.json @@ -0,0 +1,10 @@ +{ + "argument.flywheel_backend.id.unknown": "Unknown backend '%s'", + "command.flywheel.backend.get": "The current Flywheel backend is '%s'", + "command.flywheel.backend.set": "The Flywheel backend is now '%s'", + "command.flywheel.backend.set.unavailable": "The requested backend '%s' is not available", + "command.flywheel.limit_updates.get.off": "Update limiting is currently disabled", + "command.flywheel.limit_updates.get.on": "Update limiting is currently enabled", + "command.flywheel.limit_updates.set.off": "Update limiting is now disabled", + "command.flywheel.limit_updates.set.on": "Update limiting is now enabled" +}