From ec92fef4450456ea1922503c63e2f042511e76a1 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 10 Apr 2022 17:02:28 -0700 Subject: [PATCH] Material refactor pt 1 - User no longer needs to supply a key object to get an instancer - Move memoization logic outside of MaterialManager - Provide utility class for memoizing models - Vanilla instances use static objects for their models - PartialModels don't actually need reference states, use air instead - Move RenderLayer to api package - Kill lazy killable --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + gradle.properties | 2 +- .../com/jozufozu/flywheel/api/Material.java | 27 +++++--------- .../flywheel/api/MaterialManager.java | 6 +-- .../jozufozu/flywheel/api/ModelSupplier.java | 11 ++++++ .../{backend => api}/RenderLayer.java | 2 +- .../instancing/batching/BatchedMaterial.java | 7 ++-- .../instancing/batching/BatchingEngine.java | 6 +-- .../instancing/InstancedMaterial.java | 16 +++----- .../instancing/InstancedMaterialGroup.java | 2 +- .../instancing/InstancingEngine.java | 4 +- .../com/jozufozu/flywheel/core/Models.java | 37 +++++++++++++++++++ .../flywheel/core/SimpleModelSupplier.java | 25 +++++++++++++ .../flywheel/core/compile/ProgramContext.java | 2 +- .../core/crumbling/CrumblingGroup.java | 2 +- .../core/crumbling/CrumblingRenderer.java | 15 ++++---- .../flywheel/core/model/ModelUtil.java | 32 ++++++++++------ .../flywheel/event/RenderLayerEvent.java | 2 +- .../java/com/jozufozu/flywheel/util/Lazy.java | 32 +++------------- .../flywheel/util/NonNullSupplier.java | 3 +- .../flywheel/vanilla/BellInstance.java | 9 ++++- .../flywheel/vanilla/ChestInstance.java | 32 ++++++++++------ .../flywheel/vanilla/MinecartInstance.java | 10 ++++- .../flywheel/vanilla/ShulkerBoxInstance.java | 16 ++++++-- 24 files changed, 190 insertions(+), 111 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/ModelSupplier.java rename src/main/java/com/jozufozu/flywheel/{backend => api}/RenderLayer.java (97%) create mode 100644 src/main/java/com/jozufozu/flywheel/core/Models.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/SimpleModelSupplier.java diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 03c717f62..1c5db0a1d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,7 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.7.0" - "0.6.2" - "0.6.1" - "0.6.0" diff --git a/gradle.properties b/gradle.properties index 7989201c7..941a2c4c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.2 +mod_version = 0.7.0 mc_update_version = 1.18 minecraft_version = 1.18.2 forge_version = 40.0.15 diff --git a/src/main/java/com/jozufozu/flywheel/api/Material.java b/src/main/java/com/jozufozu/flywheel/api/Material.java index f6a963cf7..01c7d8b0c 100644 --- a/src/main/java/com/jozufozu/flywheel/api/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/Material.java @@ -2,44 +2,37 @@ package com.jozufozu.flywheel.api; import java.util.function.Supplier; +import com.jozufozu.flywheel.core.Models; import com.jozufozu.flywheel.core.PartialModel; -import com.jozufozu.flywheel.core.model.BlockModel; -import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.core.model.ModelUtil; -import com.jozufozu.flywheel.util.Pair; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.core.Direction; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; public interface Material { + /** * Get an instancer for the given model. Calling this method twice with the same key will return the same instancer. * - * @param key An object that uniquely identifies the model. - * @param modelSupplier A factory that creates the Model that you want to render. + * @param modelKey An object that uniquely identifies and provides the model. * @return An instancer for the given model, capable of rendering many copies for little cost. */ - Instancer model(Object key, Supplier modelSupplier); - - default Instancer getModel(PartialModel partial, BlockState referenceState) { - return model(partial, () -> new BlockModel(partial.get(), referenceState)); - } + Instancer model(ModelSupplier modelKey); default Instancer getModel(PartialModel partial) { - return model(partial, () -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState())); + return model(Models.partial(partial)); } - default Instancer getModel(PartialModel partial, BlockState referenceState, Direction dir) { - return getModel(partial, referenceState, dir, ModelUtil.rotateToFace(dir)); + default Instancer getModel(PartialModel partial, Direction dir) { + return model(Models.partial(partial, dir, () -> ModelUtil.rotateToFace(dir))); } - default Instancer getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier modelTransform) { - return model(Pair.of(dir, partial), () -> new BlockModel(partial.get(), referenceState, modelTransform.get())); + default Instancer getModel(PartialModel partial, Direction dir, Supplier modelTransform) { + return model(Models.partial(partial, dir, modelTransform)); } default Instancer getModel(BlockState toRender) { - return model(toRender, () -> new BlockModel(toRender)); + return model(Models.block(toRender)); } } diff --git a/src/main/java/com/jozufozu/flywheel/api/MaterialManager.java b/src/main/java/com/jozufozu/flywheel/api/MaterialManager.java index 84d706504..c5e82baf8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/MaterialManager.java +++ b/src/main/java/com/jozufozu/flywheel/api/MaterialManager.java @@ -1,7 +1,5 @@ package com.jozufozu.flywheel.api; -import com.jozufozu.flywheel.backend.RenderLayer; - import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Vec3i; @@ -11,10 +9,10 @@ public interface MaterialManager { * Get a material group that will render in the given layer with the given state. * * @param layer The {@link RenderLayer} you want to draw in. - * @param state The {@link RenderType} you need to draw with. + * @param type The {@link RenderType} you need to draw with. * @return A material group whose children will */ - MaterialGroup state(RenderLayer layer, RenderType state); + MaterialGroup state(RenderLayer layer, RenderType type); Vec3i getOriginCoordinate(); diff --git a/src/main/java/com/jozufozu/flywheel/api/ModelSupplier.java b/src/main/java/com/jozufozu/flywheel/api/ModelSupplier.java new file mode 100644 index 000000000..9f72f34f5 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/ModelSupplier.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api; + +import javax.annotation.Nonnull; + +import com.jozufozu.flywheel.core.model.Model; + +public interface ModelSupplier { + + @Nonnull + Model get(); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/RenderLayer.java b/src/main/java/com/jozufozu/flywheel/api/RenderLayer.java similarity index 97% rename from src/main/java/com/jozufozu/flywheel/backend/RenderLayer.java rename to src/main/java/com/jozufozu/flywheel/api/RenderLayer.java index 3f5a6dcaa..fbdede5c5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/RenderLayer.java +++ b/src/main/java/com/jozufozu/flywheel/api/RenderLayer.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend; +package com.jozufozu.flywheel.api; import javax.annotation.Nullable; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java index cf97a5b1b..16d997f89 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java @@ -7,6 +7,7 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.core.model.Model; import com.mojang.blaze3d.vertex.PoseStack; @@ -14,7 +15,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer; public class BatchedMaterial implements Material { - protected final Map> models; + protected final Map> models; private final Batched type; public BatchedMaterial(Batched type) { @@ -24,8 +25,8 @@ public class BatchedMaterial implements Material { } @Override - public Instancer model(Object key, Supplier modelSupplier) { - return models.computeIfAbsent(key, $ -> new CPUInstancer<>(type, modelSupplier.get())); + public Instancer model(ModelSupplier modelKey) { + return models.computeIfAbsent(modelKey, k -> new CPUInstancer<>(type, k.get())); } public void setupAndRenderInto(PoseStack stack, VertexConsumer buffer) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index aa6e7f683..d123964e7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; import com.jozufozu.flywheel.api.MaterialGroup; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.TaskEngine; @@ -33,8 +33,8 @@ public class BatchingEngine implements Engine { } @Override - public MaterialGroup state(RenderLayer layer, RenderType state) { - return layers.get(layer).computeIfAbsent(state, BatchedMaterialGroup::new); + public MaterialGroup state(RenderLayer layer, RenderType type) { + return layers.get(layer).computeIfAbsent(type, BatchedMaterialGroup::new); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java index 7a8373136..cf7ecfd49 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java @@ -10,6 +10,7 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.core.model.Model; @@ -19,7 +20,7 @@ import com.jozufozu.flywheel.core.model.Model; */ public class InstancedMaterial implements Material { - protected final Map> models = new HashMap<>(); + protected final Map> models = new HashMap<>(); protected final Instanced type; protected final List> uninitialized = new ArrayList<>(); @@ -27,17 +28,10 @@ public class InstancedMaterial implements Material { this.type = type; } - /** - * Get an instancer for the given model. Calling this method twice with the same key will return the same instancer. - * - * @param key An object that uniquely identifies the model. - * @param modelSupplier A factory that creates the IModel that you want to render. - * @return An instancer for the given model, capable of rendering many copies for little cost. - */ @Override - public Instancer model(Object key, Supplier modelSupplier) { - return models.computeIfAbsent(key, $ -> { - GPUInstancer instancer = new GPUInstancer<>(type, modelSupplier.get()); + public Instancer model(ModelSupplier modelKey) { + return models.computeIfAbsent(modelKey, k -> { + GPUInstancer instancer = new GPUInstancer<>(type, k.get()); uninitialized.add(instancer); return instancer; }); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java index 2bc228ed9..772259fe2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.model.FallbackAllocator; import com.jozufozu.flywheel.backend.model.ModelAllocator; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index e3efc8a71..04d8e9593 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import com.jozufozu.flywheel.api.MaterialGroup; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.core.compile.ProgramCompiler; @@ -59,7 +59,7 @@ public class InstancingEngine

implements Engine { /** * Get a material group that will render in the given layer with the given type. * - * @param layer The {@link RenderLayer} you want to draw in. + * @param layer * @param type The {@link RenderType} you need to draw with. * @return A material group whose children will */ diff --git a/src/main/java/com/jozufozu/flywheel/core/Models.java b/src/main/java/com/jozufozu/flywheel/core/Models.java new file mode 100644 index 000000000..a1d52c7ca --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/Models.java @@ -0,0 +1,37 @@ +package com.jozufozu.flywheel.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +import com.jozufozu.flywheel.api.ModelSupplier; +import com.jozufozu.flywheel.core.model.BlockModel; +import com.jozufozu.flywheel.util.Pair; +import com.mojang.blaze3d.vertex.PoseStack; + +import net.minecraft.Util; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class Models { + + public static ModelSupplier block(BlockState state) { + return BLOCK_STATE.apply(state); + } + + public static ModelSupplier partial(PartialModel partial) { + return PARTIAL.apply(partial); + } + + public static ModelSupplier partial(PartialModel partial, Direction dir, Supplier modelTransform) { + return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new SimpleModelSupplier(() -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState(), modelTransform.get()))); + } + + private static final Function BLOCK_STATE = Util.memoize(it -> new SimpleModelSupplier(() -> new BlockModel(it))); + private static final Function PARTIAL = Util.memoize(it -> new SimpleModelSupplier(() -> new BlockModel(it.get(), Blocks.AIR.defaultBlockState()))); + private static final Map, ModelSupplier> PARTIAL_DIR = new HashMap<>(); + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/SimpleModelSupplier.java b/src/main/java/com/jozufozu/flywheel/core/SimpleModelSupplier.java new file mode 100644 index 000000000..7d0256874 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/SimpleModelSupplier.java @@ -0,0 +1,25 @@ +package com.jozufozu.flywheel.core; + +import java.util.function.Supplier; + +import javax.annotation.Nonnull; + +import com.jozufozu.flywheel.api.ModelSupplier; +import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.util.Lazy; +import com.jozufozu.flywheel.util.NonNullSupplier; + +public class SimpleModelSupplier implements ModelSupplier { + + private final Lazy supplier; + + public SimpleModelSupplier(NonNullSupplier supplier) { + this.supplier = Lazy.of(supplier); + } + + @Nonnull + @Override + public Model get() { + return supplier.get(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramContext.java b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramContext.java index 2fefb12b3..3a1c72a79 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramContext.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramContext.java @@ -6,7 +6,7 @@ import javax.annotation.Nullable; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.jozufozu.flywheel.core.GameStateRegistry; import com.jozufozu.flywheel.core.shader.ProgramSpec; import com.jozufozu.flywheel.core.shader.StateSnapshot; diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java index ee113de17..668fd38bb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingGroup.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.core.crumbling; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterialGroup; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; import com.jozufozu.flywheel.util.Textures; diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index e9aca9ff3..0364a5c74 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -44,14 +44,10 @@ public class CrumblingRenderer { static RenderType _currentLayer; - private static final Lazy STATE; - private static final Lazy.KillSwitch INVALIDATOR; + private static Lazy STATE; static { - Pair, Lazy.KillSwitch> state = Lazy.ofKillable(State::new, State::kill); - - STATE = state.first(); - INVALIDATOR = state.second(); + _init(); } public static void renderBreaking(RenderLayerEvent event) { @@ -126,7 +122,12 @@ public class CrumblingRenderer { } public static void reset() { - INVALIDATOR.killValue(); + STATE.ifPresent(State::kill); + _init(); + } + + private static void _init() { + STATE = Lazy.of(State::new); } private static class State { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index 0815adf28..27a9f7851 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -2,8 +2,8 @@ package com.jozufozu.flywheel.core.model; import java.lang.reflect.Field; import java.util.Collection; +import java.util.EnumMap; import java.util.Random; -import java.util.function.Supplier; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; @@ -127,18 +127,28 @@ public class ModelUtil { return builder; } - public static Supplier rotateToFace(Direction facing) { - return () -> { - PoseStack stack = new PoseStack(); - TransformStack.cast(stack) - .centre() - .rotateToFace(facing.getOpposite()) - .unCentre(); - return stack; - }; + private static PoseStack createRotation(Direction facing) { + PoseStack stack = new PoseStack(); + TransformStack.cast(stack) + .centre() + .rotateToFace(facing.getOpposite()) + .unCentre(); + return stack; } - private static class ThreadLocalObjects { + public static PoseStack rotateToFace(Direction facing) { + return TRANSFORMS.get(facing); + } + + private static final EnumMap TRANSFORMS = new EnumMap<>(Direction.class); + + static { + for (Direction value : Direction.values()) { + TRANSFORMS.put(value, createRotation(value)); + } + } + + private static class ThreadLocalObjects { public final Random random = new Random(); public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); public final BufferBuilder unshadedBuilder = new BufferBuilder(512); diff --git a/src/main/java/com/jozufozu/flywheel/event/RenderLayerEvent.java b/src/main/java/com/jozufozu/flywheel/event/RenderLayerEvent.java index f0b54fc49..c2d321798 100644 --- a/src/main/java/com/jozufozu/flywheel/event/RenderLayerEvent.java +++ b/src/main/java/com/jozufozu/flywheel/event/RenderLayerEvent.java @@ -2,7 +2,7 @@ package com.jozufozu.flywheel.event; import javax.annotation.Nullable; -import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.api.RenderLayer; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; diff --git a/src/main/java/com/jozufozu/flywheel/util/Lazy.java b/src/main/java/com/jozufozu/flywheel/util/Lazy.java index a50c84361..85963ca10 100644 --- a/src/main/java/com/jozufozu/flywheel/util/Lazy.java +++ b/src/main/java/com/jozufozu/flywheel/util/Lazy.java @@ -1,10 +1,11 @@ package com.jozufozu.flywheel.util; import java.util.function.Consumer; +import java.util.function.Supplier; import javax.annotation.Nonnull; -public class Lazy { +public class Lazy implements Supplier { private final NonNullSupplier supplier; @@ -23,36 +24,13 @@ public class Lazy { return value; } - /** - * Provides an external facing API safe way of invalidating lazy values. - */ - public static Pair, KillSwitch> ofKillable(NonNullSupplier factory, Consumer destructor) { - Lazy lazy = new Lazy<>(factory); - - KillSwitch killSwitch = new KillSwitch<>(lazy, destructor); - - return Pair.of(lazy, killSwitch); - } - public static Lazy of(NonNullSupplier factory) { return new Lazy<>(factory); } - public static class KillSwitch { - - private final Lazy lazy; - private final Consumer finalizer; - - private KillSwitch(Lazy lazy, Consumer finalizer) { - this.lazy = lazy; - this.finalizer = finalizer; - } - - public void killValue() { - if (lazy.value != null) { - finalizer.accept(lazy.value); - lazy.value = null; - } + public void ifPresent(Consumer func) { + if (value != null) { + func.accept(value); } } } diff --git a/src/main/java/com/jozufozu/flywheel/util/NonNullSupplier.java b/src/main/java/com/jozufozu/flywheel/util/NonNullSupplier.java index e54ebcdc2..39dd7567d 100644 --- a/src/main/java/com/jozufozu/flywheel/util/NonNullSupplier.java +++ b/src/main/java/com/jozufozu/flywheel/util/NonNullSupplier.java @@ -5,5 +5,6 @@ import javax.annotation.Nonnull; @FunctionalInterface public interface NonNullSupplier { - @Nonnull T get(); + @Nonnull + T get(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index 0da987881..c0d2f95a0 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -1,9 +1,13 @@ package com.jozufozu.flywheel.vanilla; +import javax.annotation.Nonnull; + import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.SimpleModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -16,6 +20,8 @@ import net.minecraft.world.level.block.entity.BellBlockEntity; public class BellInstance extends BlockEntityInstance implements DynamicInstance { + private static final ModelSupplier MODEL = new SimpleModelSupplier(BellInstance::createBellModel); + private final OrientedData bell; private float lastRingTime = Float.NaN; @@ -59,10 +65,11 @@ public class BellInstance extends BlockEntityInstance implement private OrientedData createBellInstance() { return materialManager.defaultCutout() .material(Materials.ORIENTED) - .model(blockEntity.getType(), BellInstance::createBellModel) + .model(MODEL) .createInstance(); } + @Nonnull private static ModelPart createBellModel() { return ModelPart.builder("bell", 32, 32) .sprite(BellRenderer.BELL_RESOURCE_LOCATION.sprite()) diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index df834d326..79aa0cf5e 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -1,13 +1,16 @@ package com.jozufozu.flywheel.vanilla; import java.util.Calendar; +import java.util.function.BiFunction; import javax.annotation.Nonnull; import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.SimpleModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.materials.oriented.OrientedData; @@ -16,8 +19,10 @@ import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; +import net.minecraft.Util; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.Material; import net.minecraft.world.level.block.AbstractChestBlock; import net.minecraft.world.level.block.Block; @@ -30,6 +35,9 @@ import net.minecraft.world.level.block.state.properties.ChestType; public class ChestInstance extends BlockEntityInstance implements DynamicInstance { + private static final BiFunction LID = Util.memoize((type, sprite) -> new SimpleModelSupplier(() -> createLidModel(type, sprite))); + private static final BiFunction BASE = Util.memoize((type, sprite) -> new SimpleModelSupplier(() -> createBaseModel(type, sprite))); + private final OrientedData body; private final ModelData lid; @@ -111,7 +119,7 @@ public class ChestInstance extends Block return materialManager.solid(RenderType.entitySolid(renderMaterial.atlasLocation())) .material(Materials.ORIENTED) - .model("base_" + renderMaterial.texture(), this::getBaseModel) + .model(BASE.apply(chestType, renderMaterial.sprite())) .createInstance(); } @@ -119,15 +127,15 @@ public class ChestInstance extends Block return materialManager.solid(RenderType.entitySolid(renderMaterial.atlasLocation())) .material(Materials.TRANSFORMED) - .model("lid_" + renderMaterial.texture(), this::getLidModel) + .model(LID.apply(chestType, renderMaterial.sprite())) .createInstance(); } - private ModelPart getBaseModel() { + private static ModelPart createBaseModel(ChestType type, TextureAtlasSprite sprite) { - return switch (chestType) { + return switch (type) { case LEFT -> ModelPart.builder("chest_base_left", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 19) .start(0, 0, 1) @@ -135,7 +143,7 @@ public class ChestInstance extends Block .endCuboid() .build(); case RIGHT -> ModelPart.builder("chest_base_right", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 19) .start(1, 0, 1) @@ -143,7 +151,7 @@ public class ChestInstance extends Block .endCuboid() .build(); default -> ModelPart.builder("chest_base", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 19) .start(1, 0, 1) @@ -154,11 +162,11 @@ public class ChestInstance extends Block } - private ModelPart getLidModel() { + private static ModelPart createLidModel(ChestType type, TextureAtlasSprite sprite) { - return switch (chestType) { + return switch (type) { case LEFT -> ModelPart.builder("chest_lid_left", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 0) .start(0, 0, 1) @@ -170,7 +178,7 @@ public class ChestInstance extends Block .endCuboid() .build(); case RIGHT -> ModelPart.builder("chest_lid_right", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 0) .start(1, 0, 1) @@ -182,7 +190,7 @@ public class ChestInstance extends Block .endCuboid() .build(); default -> ModelPart.builder("chest_lid", 64, 64) - .sprite(renderMaterial.sprite()) + .sprite(sprite) .cuboid() .textureOffset(0, 0) .start(1, 0, 1) diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index c094eaf25..30f66daf0 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -1,10 +1,14 @@ package com.jozufozu.flywheel.vanilla; +import javax.annotation.Nonnull; + import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.SimpleModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.model.Model; @@ -25,6 +29,7 @@ import net.minecraft.world.phys.Vec3; public class MinecartInstance extends EntityInstance implements DynamicInstance, TickableInstance { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); + private static final ModelSupplier MODEL = new SimpleModelSupplier(MinecartInstance::getBodyModel); private final PoseStack stack = new PoseStack(); @@ -151,11 +156,12 @@ public class MinecartInstance extends EntityInstance private ModelData getBody() { return materialManager.solid(RenderType.entitySolid(MINECART_LOCATION)) .material(Materials.TRANSFORMED) - .model(entity.getType(), this::getBodyModel) + .model(MODEL) .createInstance(); } - private Model getBodyModel() { + @Nonnull + private static Model getBodyModel() { int y = -3; return ModelPart.builder("minecart", 64, 32) .cuboid().invertYZ().start(-10, -8, -y).size(20, 16, 2).textureOffset(0, 10).rotateZ((float) Math.PI).rotateX(((float)Math.PI / 2F)).endCuboid() diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index a55e62eb8..95a69b5bc 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -1,9 +1,13 @@ package com.jozufozu.flywheel.vanilla; +import java.util.function.Function; + import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.ModelSupplier; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.SimpleModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -12,6 +16,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; +import net.minecraft.Util; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -22,6 +27,9 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; public class ShulkerBoxInstance extends BlockEntityInstance implements DynamicInstance { + private static final Function BASE = Util.memoize(it -> new SimpleModelSupplier(() -> makeBaseModel(it))); + private static final Function LID = Util.memoize(it -> new SimpleModelSupplier(() -> makeLidModel(it))); + private final TextureAtlasSprite texture; private final ModelData base; @@ -93,18 +101,18 @@ public class ShulkerBoxInstance extends BlockEntityInstance