A different type of translation

- Display actual backend instead of preferred backend when checking
backend
- Remove engine message and use standard messages that display backend
ID
- Simplify command code
- Replace all literal components with translatable components
- Pass 1 instead of 0 for partialTick on tick
- Extract base AtomicReferenceCounted and ReferenceCounted abstract
classes
- Double buffer capacity instead of adding constant on resize in
VertexWriter
- Move Samplers class from backend.engine to backend
This commit is contained in:
PepperCode1 2024-02-28 21:41:16 -08:00
parent c931e84b65
commit c3307630b2
25 changed files with 165 additions and 176 deletions

View file

@ -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) {

View file

@ -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<Backend> REGISTRY = InternalFlywheelApi.INSTANCE.createIdRegistry();
/**
* Get a message to display to the user when the engine is enabled.
*/
Component engineMessage();
/**
* Create a new engine instance.
*/

View file

@ -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() {
}
}

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.engine;
package com.jozufozu.flywheel.backend;
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;

View file

@ -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<ContextShader> REGISTRY = InternalFlywheelApi.INSTANCE.createRegistry();

View file

@ -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");

View file

@ -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<PipelineProgramKey> pipelineKeys, List<SourceComponent> vertexComponents, List<SourceComponent> 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);

View file

@ -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;

View file

@ -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"))

View file

@ -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;

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -182,8 +182,8 @@ public class IndirectCullingGroup<I extends Instance> {
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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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();

View file

@ -23,7 +23,7 @@ public class BackendArgument implements ArgumentType<Backend> {
private static final List<String> 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();

View file

@ -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<CommandSourceStack> command = Commands.literal("flywheel");
addValue(command, config.client.backend, "backend", (builder, value) ->
builder
ConfigValue<String> 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 <T extends ConfigValue<?>> void addValue(LiteralArgumentBuilder<CommandSourceStack> command, T value, String subcommand, BiConsumer<LiteralArgumentBuilder<CommandSourceStack>, T> consumer) {
LiteralArgumentBuilder<CommandSourceStack> builder = Commands.literal(subcommand);
consumer.accept(builder, value);
command.then(builder);
}
private static void booleanValueCommand(LiteralArgumentBuilder<CommandSourceStack> builder, ConfigValue<Boolean> value, BiConsumer<CommandSourceStack, Boolean> displayAction, BiConsumer<CommandSourceStack, Boolean> setAction) {
builder
private static LiteralArgumentBuilder<CommandSourceStack> booleanValueCommand(LiteralArgumentBuilder<CommandSourceStack> builder, ConfigValue<Boolean> value, BiConsumer<CommandSourceStack, Boolean> displayAction, BiConsumer<CommandSourceStack, Boolean> 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);
}
}

View file

@ -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.");
})

View file

@ -70,7 +70,7 @@ public class VisualManagerImpl<T, S extends Storage<T>> implements VisualManager
}
public Plan<VisualTickContext> tickPlan() {
return SimplePlan.<VisualTickContext>of(context -> processQueue(0))
return SimplePlan.<VisualTickContext>of(context -> processQueue(1))
.then(storage.tickPlan());
}
}

View file

@ -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<LevelAccessor, Engine> engineFactory;
private final Supplier<Backend> fallback;
private final BooleanSupplier isSupported;
public SimpleBackend(Component engineMessage, Function<LevelAccessor, Engine> engineFactory, Supplier<Backend> fallback, BooleanSupplier isSupported) {
this.engineMessage = engineMessage;
public SimpleBackend(Function<LevelAccessor, Engine> engineFactory, Supplier<Backend> 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<LevelAccessor, Engine> engineFactory;
private Supplier<Backend> fallback = BackendManager::getOffBackend;
private BooleanSupplier isSupported;
public Builder engineMessage(Component engineMessage) {
this.engineMessage = engineMessage;
return this;
}
public Builder engineFactory(Function<LevelAccessor, Engine> 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));
}
}
}

View file

@ -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);
}
}

View file

@ -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"
}