From b65cb7eb7f73186177657c2ef2b302a9518ef40c Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Tue, 4 Apr 2023 12:36:54 -0700 Subject: [PATCH] Instance Refactor I --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - gradle.properties | 2 +- .../java/com/jozufozu/flywheel/Flywheel.java | 8 +- .../jozufozu/flywheel/api/backend/Engine.java | 2 +- .../api/instance/BlockEntityInstance.java | 11 + .../api/instance/DynamicInstance.java | 5 +- .../flywheel/api/instance/EntityInstance.java | 6 + .../flywheel/api/instance/Instance.java | 38 ++- .../api/instance/TickableInstance.java | 5 +- .../BlockEntityInstancingController.java | 4 +- .../EntityInstancingController.java | 4 +- .../InstancingControllerRegistry.java | 60 +++++ .../flywheel/api/instance/effect/Effect.java | 10 + .../api/instancer/InstancerProvider.java | 2 +- .../flywheel/api/registry/IdRegistry.java | 4 + .../backend/compile/CullingContextSet.java | 2 +- .../flywheel/backend/compile/FlwCompiler.java | 6 +- .../backend/compile/PipelineContextSet.java | 4 +- .../AbstractInstancer.java | 2 +- .../{instancing => engine}/InstancerKey.java | 2 +- .../{uniform => engine}/UniformBuffer.java | 2 +- .../engine/batching/BatchingEngine.java | 2 +- .../batching/BatchingTransformManager.java | 2 +- .../backend/engine/batching/CPUInstancer.java | 2 +- .../engine/indirect/IndirectCullingGroup.java | 2 +- .../backend/engine/indirect/IndirectDraw.java | 6 +- .../engine/indirect/IndirectDrawManager.java | 2 +- .../engine/indirect/IndirectDrawSet.java | 4 +- .../engine/indirect/IndirectEngine.java | 2 +- .../engine/indirect/IndirectInstancer.java | 2 +- .../backend/engine/indirect/ShaderState.java | 8 - .../engine/instancing/GPUInstancer.java | 2 +- .../instancing/InstancingDrawManager.java | 2 +- .../engine/instancing/InstancingEngine.java | 10 +- .../backend/instancing/InstanceWorld.java | 9 +- .../instancing/InstancedRenderDispatcher.java | 10 +- .../backend/instancing/effect/Effect.java | 11 - .../entity/EntityInstanceManager.java | 47 ---- .../BlockEntityInstanceManager.java | 30 +-- .../EffectInstanceManager.java | 54 ++-- .../manager/EntityInstanceManager.java | 53 ++++ .../{ => manager}/InstanceManager.java | 251 +++++++++--------- .../ratelimit/BandedPrimeLimiter.java | 4 +- .../instancing/ratelimit/NonLimiter.java | 1 - .../instancing/storage/AbstractStorage.java | 30 +-- .../instancing/storage/One2OneStorage.java | 53 ++-- .../backend/instancing/storage/Storage.java | 10 +- .../backend/task/SerialTaskExecutor.java | 1 - .../jozufozu/flywheel/config/FlwCommands.java | 2 +- .../jozufozu/flywheel/config/FlwConfig.java | 11 +- .../extension/BlockEntityTypeExtension.java | 2 +- .../extension/EntityTypeExtension.java | 2 +- .../flywheel/impl/BackendManagerImpl.java | 2 +- .../flywheel/impl/IdRegistryImpl.java | 19 ++ .../jozufozu/flywheel/impl/RegistryImpl.java | 1 + .../InstancingControllerRegistryImpl.java | 37 +++ .../AbstractBlockEntityInstance.java} | 12 +- .../instance/AbstractEntityInstance.java} | 13 +- .../instance}/AbstractInstance.java | 81 ++---- .../instance/InstancingControllerHelper.java} | 78 ++---- ...SimpleBlockEntityInstancingController.java | 8 +- .../SimpleEntityInstancingController.java | 8 +- ...rialIndicies.java => MaterialIndices.java} | 48 ++-- .../flywheel/mixin/BlockEntityTypeMixin.java | 2 +- .../flywheel/mixin/ClientLevelMixin.java | 4 +- .../flywheel/mixin/EntityTypeMixin.java | 2 +- .../ChunkRebuildHooksMixin.java | 6 +- .../flywheel/vanilla/BellInstance.java | 6 +- .../flywheel/vanilla/ChestInstance.java | 6 +- .../flywheel/vanilla/MinecartInstance.java | 6 +- .../flywheel/vanilla/ShulkerBoxInstance.java | 6 +- .../vanilla/effect/ExampleEffect.java | 8 +- 72 files changed, 625 insertions(+), 535 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java rename src/main/java/com/jozufozu/flywheel/api/instance/{blockentity => controller}/BlockEntityInstancingController.java (87%) rename src/main/java/com/jozufozu/flywheel/api/instance/{entity => controller}/EntityInstancingController.java (87%) create mode 100644 src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java rename src/main/java/com/jozufozu/flywheel/backend/{instancing => engine}/AbstractInstancer.java (98%) rename src/main/java/com/jozufozu/flywheel/backend/{instancing => engine}/InstancerKey.java (86%) rename src/main/java/com/jozufozu/flywheel/backend/{uniform => engine}/UniformBuffer.java (98%) delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/engine/indirect/ShaderState.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/effect/Effect.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java rename src/main/java/com/jozufozu/flywheel/backend/instancing/{blockentity => manager}/BlockEntityInstanceManager.java (69%) rename src/main/java/com/jozufozu/flywheel/backend/instancing/{effect => manager}/EffectInstanceManager.java (65%) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java rename src/main/java/com/jozufozu/flywheel/backend/instancing/{ => manager}/InstanceManager.java (82%) create mode 100644 src/main/java/com/jozufozu/flywheel/impl/instance/InstancingControllerRegistryImpl.java rename src/main/java/com/jozufozu/flywheel/{backend/instancing/blockentity/BlockEntityInstance.java => lib/instance/AbstractBlockEntityInstance.java} (85%) rename src/main/java/com/jozufozu/flywheel/{backend/instancing/entity/EntityInstance.java => lib/instance/AbstractEntityInstance.java} (85%) rename src/main/java/com/jozufozu/flywheel/{backend/instancing => lib/instance}/AbstractInstance.java (52%) rename src/main/java/com/jozufozu/flywheel/{api/instance/InstancedRenderRegistry.java => lib/instance/InstancingControllerHelper.java} (54%) rename src/main/java/com/jozufozu/flywheel/lib/material/{MaterialIndicies.java => MaterialIndices.java} (71%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2e779635d..3dbe6f0b0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,7 +59,6 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: - - "0.7.0" - "0.6.8.a" - "0.6.8" - "0.6.7" diff --git a/gradle.properties b/gradle.properties index f84cf5fd1..bcf602c21 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.7.0 +mod_version = 1.0.0-alpha artifact_minecraft_version = 1.18.2 minecraft_version = 1.18.2 diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index d56c37768..7d6967133 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -17,7 +17,7 @@ import com.jozufozu.flywheel.impl.RegistryImpl; import com.jozufozu.flywheel.lib.backend.Backends; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.format.Formats; -import com.jozufozu.flywheel.lib.material.MaterialIndicies; +import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.Models; import com.jozufozu.flywheel.lib.model.PartialModel; @@ -111,7 +111,7 @@ public class Flywheel { Contexts.init(); Pipelines.init(); - MaterialIndicies.init(); + MaterialIndices.init(); VanillaInstances.init(); @@ -126,10 +126,10 @@ public class Flywheel { } private static void setup(final FMLCommonSetupEvent event) { - ArgumentTypes.register(rl("backend").toString(), BackendArgument.class, new EmptyArgumentSerializer<>(BackendArgument::getInstance)); - RegistryImpl.freezeAll(); IdRegistryImpl.freezeAll(); + + ArgumentTypes.register(rl("backend").toString(), BackendArgument.class, new EmptyArgumentSerializer<>(BackendArgument::getInstance)); } public static ArtifactVersion getVersion() { diff --git a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java index 5c43fec26..b77b19e6d 100644 --- a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java +++ b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java @@ -3,7 +3,7 @@ package com.jozufozu.flywheel.api.backend; import java.util.List; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; public interface Engine extends RenderDispatcher, InstancerProvider { void attachManagers(InstanceManager... listener); diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java new file mode 100644 index 000000000..0ea0acd7e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api.instance; + +import java.util.List; + +import com.jozufozu.flywheel.api.instancer.InstancedPart; + +import net.minecraft.world.level.block.entity.BlockEntity; + +public interface BlockEntityInstance extends Instance { + List getCrumblingParts(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java index 2a4976a48..6f49b4f1b 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java @@ -2,11 +2,10 @@ package com.jozufozu.flywheel.api.instance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.Instancer; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; /** - * An interface giving {@link BlockEntityInstance}s a hook to have a function called at - * the start of a frame. By implementing {@link DynamicInstance}, a {@link BlockEntityInstance} + * An interface giving {@link Instance}s a hook to have a function called at + * the start of a frame. By implementing {@link DynamicInstance}, an {@link Instance} * can animate its models in ways that could not be easily achieved by shader attribute * parameterization. * diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java new file mode 100644 index 000000000..668ffa749 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java @@ -0,0 +1,6 @@ +package com.jozufozu.flywheel.api.instance; + +import net.minecraft.world.entity.Entity; + +public interface EntityInstance extends Instance { +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java index 89ab8e959..f29b4b683 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java @@ -4,9 +4,38 @@ import org.joml.FrustumIntersection; import net.minecraft.core.BlockPos; +/** + * A general interface providing information about any type of thing that could use Flywheel's instanced rendering. + */ public interface Instance { BlockPos getWorldPosition(); + /** + * Initialize parts here. + */ + void init(); + + /** + * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. + * + *

If your animations are complex or more CPU driven, see {@link DynamicInstance} or {@link TickableInstance}. + */ + void update(); + + /** + * When an instance is reset, the instance is deleted and re-created. + * + *

+ * Just before {@link #update()} would be called, {@code shouldReset()} is checked. + * If this function returns {@code true}, then this instance will be {@link #delete deleted}, + * and another instance will be constructed to replace it. This allows for more sane resource + * acquisition compared to trying to update everything within the lifetime of an instance. + *

+ * + * @return {@code true} if this instance should be discarded and refreshed. + */ + boolean shouldReset(); + /** * Check this instance against a frustum.

* An implementor may choose to return a constant to skip the frustum check. @@ -15,5 +44,12 @@ public interface Instance { */ boolean checkFrustum(FrustumIntersection frustum); - boolean isRemoved(); + /** + * Free any acquired resources. + */ + void delete(); + + // TODO + @Deprecated + void removeNow(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java index 1d114fa14..bc1ddc153 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java @@ -2,11 +2,10 @@ package com.jozufozu.flywheel.api.instance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.Instancer; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; /** - * An interface giving {@link BlockEntityInstance}s a hook to have a function called at - * the end of every tick. By implementing {@link TickableInstance}, a {@link BlockEntityInstance} + * An interface giving {@link Instance}s a hook to have a function called at + * the end of every tick. By implementing {@link TickableInstance}, an {@link Instance} * can update frequently, but not every frame. *
There are a few cases in which this should be considered over {@link DynamicInstance}: *

    diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/blockentity/BlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java similarity index 87% rename from src/main/java/com/jozufozu/flywheel/api/instance/blockentity/BlockEntityInstancingController.java rename to src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java index f8d8d93b7..e16e20694 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/blockentity/BlockEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java @@ -1,7 +1,7 @@ -package com.jozufozu.flywheel.api.instance.blockentity; +package com.jozufozu.flywheel.api.instance.controller; +import com.jozufozu.flywheel.api.instance.BlockEntityInstance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/entity/EntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java similarity index 87% rename from src/main/java/com/jozufozu/flywheel/api/instance/entity/EntityInstancingController.java rename to src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java index 3bc331a6f..a9278e6f7 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/entity/EntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java @@ -1,7 +1,7 @@ -package com.jozufozu.flywheel.api.instance.entity; +package com.jozufozu.flywheel.api.instance.controller; +import com.jozufozu.flywheel.api.instance.EntityInstance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import net.minecraft.world.entity.Entity; diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java new file mode 100644 index 000000000..c51759d92 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java @@ -0,0 +1,60 @@ +package com.jozufozu.flywheel.api.instance.controller; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.impl.instance.InstancingControllerRegistryImpl; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +/** + * A utility class for registering and retrieving {@code InstancingController}s. + */ +public final class InstancingControllerRegistry { + /** + * Gets the instancing controller for the given block entity type, if one exists. + * @param type The block entity type to get the instancing controller for. + * @param The type of the block entity. + * @return The instancing controller for the given block entity type, or {@code null} if none exists. + */ + @Nullable + public static BlockEntityInstancingController getController(BlockEntityType type) { + return InstancingControllerRegistryImpl.getController(type); + } + + /** + * Gets the instancing controller for the given entity type, if one exists. + * @param type The entity type to get the instancing controller for. + * @param The type of the entity. + * @return The instancing controller for the given entity type, or {@code null} if none exists. + */ + @Nullable + public static EntityInstancingController getController(EntityType type) { + return InstancingControllerRegistryImpl.getController(type); + } + + /** + * Sets the instancing controller for the given block entity type. + * @param type The block entity type to set the instancing controller for. + * @param instancingController The instancing controller to set. + * @param The type of the block entity. + */ + public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { + InstancingControllerRegistryImpl.setController(type, instancingController); + } + + /** + * Sets the instancing controller for the given entity type. + * @param type The entity type to set the instancing controller for. + * @param instancingController The instancing controller to set. + * @param The type of the entity. + */ + public static void setController(EntityType type, EntityInstancingController instancingController) { + InstancingControllerRegistryImpl.setController(type, instancingController); + } + + private InstancingControllerRegistry() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java b/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java new file mode 100644 index 000000000..96cde3f0b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java @@ -0,0 +1,10 @@ +package com.jozufozu.flywheel.api.instance.effect; + +import java.util.Collection; + +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instancer.InstancerProvider; + +public interface Effect { + Collection createInstances(InstancerProvider instancerManager); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java b/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java index b2738c603..92677804f 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java +++ b/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java @@ -14,6 +14,6 @@ public interface InstancerProvider { */ Instancer getInstancer(StructType type, Model model, RenderStage stage); - // TODO: this method does not belong in the interface + // TODO: this method does not belong in this interface Vec3i getOriginCoordinate(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/registry/IdRegistry.java b/src/main/java/com/jozufozu/flywheel/api/registry/IdRegistry.java index 6beb286b3..d9ee732dd 100644 --- a/src/main/java/com/jozufozu/flywheel/api/registry/IdRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/api/registry/IdRegistry.java @@ -21,6 +21,10 @@ public interface IdRegistry extends Iterable { @Nullable ResourceLocation getId(T object); + T getOrThrow(ResourceLocation id); + + ResourceLocation getIdOrThrow(T object); + @Unmodifiable Set getAllIds(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java index bc12bb992..e23755e51 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java @@ -9,7 +9,7 @@ import com.jozufozu.flywheel.api.struct.StructType; public class CullingContextSet { static CullingContextSet create() { var builder = new CullingContextSet(); - for (StructType structType : StructType.REGISTRY.getAll()) { + for (StructType structType : StructType.REGISTRY) { builder.add(structType); } return builder; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java index d84d6aad2..910942501 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java @@ -26,7 +26,7 @@ import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.generate.FnSignature; import com.jozufozu.flywheel.glsl.generate.GlslExpr; -import com.jozufozu.flywheel.lib.material.MaterialIndicies; +import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.lib.pipeline.Pipelines; import com.jozufozu.flywheel.util.StringUtil; @@ -55,12 +55,12 @@ public class FlwCompiler { this.sources = sources; this.vertexMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("vertex_material_adapter")) - .materialSources(MaterialIndicies.getAllVertexShaders()) + .materialSources(MaterialIndices.getAllVertexShaders()) .adapt(FnSignature.ofVoid("flw_materialVertex")) .switchOn(GlslExpr.variable("flw_materialVertexID")) .build(sources); this.fragmentMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("fragment_material_adapter")) - .materialSources(MaterialIndicies.getAllFragmentShaders()) + .materialSources(MaterialIndices.getAllFragmentShaders()) .adapt(FnSignature.ofVoid("flw_materialFragment")) .adapt(FnSignature.create() .returnType("bool") diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java index 103e47406..56fa3db8d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java @@ -24,8 +24,8 @@ public class PipelineContextSet { static PipelineContextSet create() { var builder = new PipelineContextSet(); for (Pipeline pipelineShader : availablePipelineShaders()) { - for (StructType structType : StructType.REGISTRY.getAll()) { - for (VertexType vertexType : VertexType.REGISTRY.getAll()) { + for (StructType structType : StructType.REGISTRY) { + for (VertexType vertexType : VertexType.REGISTRY) { builder.add(vertexType, structType, Contexts.WORLD, pipelineShader); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java similarity index 98% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java rename to src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java index 9bbcc3c2e..bc7f515b1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.instancing; +package com.jozufozu.flywheel.backend.engine; import java.util.ArrayList; import java.util.BitSet; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancerKey.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java similarity index 86% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/InstancerKey.java rename to src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java index 22b8c1d02..8be8b6116 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancerKey.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.instancing; +package com.jozufozu.flywheel.backend.engine; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instancer.InstancedPart; diff --git a/src/main/java/com/jozufozu/flywheel/backend/uniform/UniformBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java similarity index 98% rename from src/main/java/com/jozufozu/flywheel/backend/uniform/UniformBuffer.java rename to src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java index d68c2c5b3..747bfcfd9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/uniform/UniformBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.uniform; +package com.jozufozu.flywheel.backend.engine; import java.util.List; import java.util.Set; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java index 50500441d..91f4c688d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java @@ -10,7 +10,7 @@ import com.jozufozu.flywheel.api.instancer.Instancer; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.task.TaskExecutor; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; import com.jozufozu.flywheel.util.FlwUtil; import com.mojang.blaze3d.vertex.PoseStack; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java index 4491e9710..bc3240d27 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java @@ -20,7 +20,7 @@ import com.jozufozu.flywheel.api.instancer.Instancer; import com.jozufozu.flywheel.api.model.Mesh; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.instancing.InstancerKey; +import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java index 6bffb6938..29b17dc2f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java @@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.engine.batching; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; +import com.jozufozu.flywheel.backend.engine.AbstractInstancer; public class CPUInstancer extends AbstractInstancer { 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 16e7763aa..f60427a53 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 @@ -16,7 +16,7 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.compile.FlwCompiler; -import com.jozufozu.flywheel.backend.uniform.UniformBuffer; +import com.jozufozu.flywheel.backend.engine.UniformBuffer; import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.pipeline.Pipelines; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java index 2ddf7903f..fa2bbed67 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java @@ -5,7 +5,7 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.lib.material.MaterialIndicies; +import com.jozufozu.flywheel.lib.material.MaterialIndices; public final class IndirectDraw { private final IndirectInstancer instancer; @@ -25,8 +25,8 @@ public final class IndirectDraw { this.stage = stage; this.mesh = mesh; - this.vertexMaterialID = MaterialIndicies.getVertexShaderIndex(material.vertexShader()); - this.fragmentMaterialID = MaterialIndicies.getFragmentShaderIndex(material.fragmentShader()); + this.vertexMaterialID = MaterialIndices.getVertexShaderIndex(material); + this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material); } public void prepare(int baseInstance) { 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 7cb47a1ae..316335d83 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 @@ -11,7 +11,7 @@ import com.jozufozu.flywheel.api.instancer.Instancer; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.backend.instancing.InstancerKey; +import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.jozufozu.flywheel.util.Pair; public class IndirectDrawManager { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java index 9a1e8c28f..dd80b96e2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java @@ -13,7 +13,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.lib.material.MaterialIndicies; +import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.util.Textures; public class IndirectDrawSet { @@ -50,7 +50,7 @@ public class IndirectDrawSet { multiDraws.clear(); // sort by stage, then material indirectDraws.sort(Comparator.comparing(IndirectDraw::stage) - .thenComparing(draw -> MaterialIndicies.getMaterialIndex(draw.material()))); + .thenComparing(draw -> MaterialIndices.getMaterialIndex(draw.material()))); for (int start = 0, i = 0; i < indirectDraws.size(); i++) { var draw = indirectDraws.get(i); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java index 8dc9b338f..ce4adfefc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java @@ -15,7 +15,7 @@ import com.jozufozu.flywheel.api.instancer.Instancer; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.task.TaskExecutor; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.jozufozu.flywheel.util.FlwUtil; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java index cf8fca1c0..b21bb0c89 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java @@ -5,7 +5,7 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; +import com.jozufozu.flywheel.backend.engine.AbstractInstancer; public class IndirectInstancer extends AbstractInstancer { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/ShaderState.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/ShaderState.java deleted file mode 100644 index 5c1cec97e..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/ShaderState.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.jozufozu.flywheel.backend.engine.indirect; - -import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.api.vertex.VertexType; - -public record ShaderState(Material material, VertexType vertex, StructType instance) { -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java index a3662cfd5..ce7058c5b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java @@ -8,7 +8,7 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; +import com.jozufozu.flywheel.backend.engine.AbstractInstancer; import com.jozufozu.flywheel.gl.array.GlVertexArray; import com.jozufozu.flywheel.gl.buffer.GlBuffer; import com.jozufozu.flywheel.gl.buffer.GlBufferType; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java index 459397b3d..89cf04c4c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java @@ -20,7 +20,7 @@ import com.jozufozu.flywheel.api.model.Mesh; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.backend.instancing.InstancerKey; +import com.jozufozu.flywheel.backend.engine.InstancerKey; public class InstancingDrawManager { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java index 88e67b26d..d799ee70c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java @@ -16,11 +16,11 @@ import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.task.TaskExecutor; import com.jozufozu.flywheel.backend.compile.FlwCompiler; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; -import com.jozufozu.flywheel.backend.uniform.UniformBuffer; +import com.jozufozu.flywheel.backend.engine.UniformBuffer; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; -import com.jozufozu.flywheel.lib.material.MaterialIndicies; +import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.lib.pipeline.Pipelines; import com.jozufozu.flywheel.util.FlwUtil; import com.mojang.blaze3d.systems.RenderSystem; @@ -121,8 +121,8 @@ public class InstancingEngine implements Engine { UniformBuffer.syncAndBind(program); var uniformLocation = program.getUniformLocation("_flw_materialID_instancing"); - var vertexID = MaterialIndicies.getVertexShaderIndex(material.vertexShader()); - var fragmentID = MaterialIndicies.getFragmentShaderIndex(material.fragmentShader()); + var vertexID = MaterialIndices.getVertexShaderIndex(material); + var fragmentID = MaterialIndices.getFragmentShaderIndex(material); GL32.glUniform2ui(uniformLocation, vertexID, fragmentID); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index 5b8cb0b46..add8a8e18 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -7,11 +7,12 @@ import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; +import com.jozufozu.flywheel.api.instance.effect.Effect; import com.jozufozu.flywheel.backend.BackendUtil; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; -import com.jozufozu.flywheel.backend.instancing.effect.Effect; -import com.jozufozu.flywheel.backend.instancing.effect.EffectInstanceManager; -import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.BlockEntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.EffectInstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.EntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor; import com.jozufozu.flywheel.extension.ClientLevelExtension; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index 5be6f8a6c..ffee63a77 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -6,8 +6,10 @@ import com.jozufozu.flywheel.api.backend.BackendManager; import com.jozufozu.flywheel.api.event.BeginFrameEvent; import com.jozufozu.flywheel.api.event.ReloadRenderersEvent; import com.jozufozu.flywheel.api.event.RenderStageEvent; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.effect.Effect; import com.jozufozu.flywheel.backend.BackendUtil; -import com.jozufozu.flywheel.backend.instancing.effect.Effect; +import com.jozufozu.flywheel.backend.instancing.manager.InstanceManager; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -26,7 +28,7 @@ public class InstancedRenderDispatcher { private static final WorldAttached instanceWorlds = new WorldAttached<>(InstanceWorld::create); /** - * Call this when you want to manually run {@link AbstractInstance#update()}. + * Call this when you want to manually run {@link Instance#update()}. * @param blockEntity The block entity whose instance you want to update. */ public static void enqueueUpdate(BlockEntity blockEntity) { @@ -38,7 +40,7 @@ public class InstancedRenderDispatcher { } /** - * Call this when you want to manually run {@link AbstractInstance#update()}. + * Call this when you want to manually run {@link Instance#update()}. * @param entity The entity whose instance you want to update. */ public static void enqueueUpdate(Entity entity) { @@ -118,7 +120,7 @@ public class InstancedRenderDispatcher { InstanceWorld instanceWorld = instanceWorlds.get(Minecraft.getInstance().level); debug.add("Update limiting: " + FlwCommands.boolToText(FlwConfig.get().limitUpdates()).getString()); - debug.add("B: " + instanceWorld.blockEntities.getObjectCount() + ", E: " + instanceWorld.entities.getObjectCount()); + debug.add("B: " + instanceWorld.blockEntities.getInstanceCount() + ", E: " + instanceWorld.entities.getInstanceCount()); instanceWorld.engine.addDebugInfo(debug); } else { debug.add("Disabled"); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/Effect.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/Effect.java deleted file mode 100644 index d3bf8057e..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/Effect.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.effect; - -import java.util.Collection; - -import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; - -public interface Effect { - - Collection createInstances(InstancerProvider instancerManager); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java deleted file mode 100644 index bb3c13c5d..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.entity; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.BackendUtil; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; -import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; - -public class EntityInstanceManager extends InstanceManager { - - private final One2OneStorage storage; - - public EntityInstanceManager(InstancerProvider instancerManager) { - storage = new One2OneStorage<>(instancerManager) { - @Override - protected @Nullable AbstractInstance createRaw(Entity obj) { - return InstancedRenderRegistry.createInstance(this.instancerManager, obj); - } - }; - } - - @Override - public One2OneStorage getStorage() { - return storage; - } - - @Override - protected boolean canCreateInstance(Entity entity) { - if (!entity.isAlive()) { - return false; - } - - if (!InstancedRenderRegistry.canInstance(entity.getType())) { - return false; - } - - Level level = entity.level; - - return BackendUtil.isFlywheelLevel(level); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java similarity index 69% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java index 571d9df0d..821f10bd2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java @@ -1,14 +1,16 @@ -package com.jozufozu.flywheel.backend.instancing.blockentity; +package com.jozufozu.flywheel.backend.instancing.manager; import java.util.List; -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.instance.BlockEntityInstance; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.backend.BackendUtil; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage; import com.jozufozu.flywheel.backend.instancing.storage.Storage; +import com.jozufozu.flywheel.lib.instance.InstancingControllerHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -18,7 +20,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; public class BlockEntityInstanceManager extends InstanceManager { - private final BlockEntityStorage storage; public BlockEntityInstanceManager(InstancerProvider instancerManager) { @@ -26,7 +27,7 @@ public class BlockEntityInstanceManager extends InstanceManager { } @Override - public Storage getStorage() { + protected Storage getStorage() { return storage; } @@ -43,7 +44,7 @@ public class BlockEntityInstanceManager extends InstanceManager { return false; } - if (!InstancedRenderRegistry.canInstance(blockEntity.getType())) { + if (!InstancingControllerHelper.canInstance(blockEntity.getType())) { return false; } @@ -68,18 +69,17 @@ public class BlockEntityInstanceManager extends InstanceManager { return false; } - public static class BlockEntityStorage extends One2OneStorage { + private static class BlockEntityStorage extends One2OneStorage { + private final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); - final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); - - - public BlockEntityStorage(InstancerProvider manager) { - super(manager); + public BlockEntityStorage(InstancerProvider instancerManager) { + super(instancerManager); } @Override - protected AbstractInstance createRaw(BlockEntity obj) { - var instance = InstancedRenderRegistry.createInstance(instancerManager, obj); + @Nullable + protected Instance createRaw(BlockEntity obj) { + BlockEntityInstance instance = InstancingControllerHelper.createInstance(instancerManager, obj); if (instance != null) { BlockPos blockPos = obj.getBlockPos(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java similarity index 65% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java index 8a0fe8da3..99c2d4b7d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java @@ -1,18 +1,16 @@ -package com.jozufozu.flywheel.backend.instancing.effect; +package com.jozufozu.flywheel.backend.instancing.manager; import java.util.ArrayList; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.effect.Effect; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.storage.AbstractStorage; import com.jozufozu.flywheel.backend.instancing.storage.Storage; -import com.jozufozu.flywheel.lib.light.LightUpdater; public class EffectInstanceManager extends InstanceManager { - private final EffectStorage storage; public EffectInstanceManager(InstancerProvider instancerManager) { @@ -20,7 +18,7 @@ public class EffectInstanceManager extends InstanceManager { } @Override - public Storage getStorage() { + protected Storage getStorage() { return storage; } @@ -29,9 +27,8 @@ public class EffectInstanceManager extends InstanceManager { return true; } - public static class EffectStorage extends AbstractStorage { - - private final Multimap instances; + private static class EffectStorage extends AbstractStorage { + private final Multimap instances; public EffectStorage(InstancerProvider manager) { super(manager); @@ -39,21 +36,13 @@ public class EffectInstanceManager extends InstanceManager { } @Override - public int getObjectCount() { - return instances.size(); - } - - @Override - public Iterable allInstances() { + public Iterable getAllInstances() { return instances.values(); } @Override - public void invalidate() { - instances.values().forEach(AbstractInstance::removeAndMark); - instances.clear(); - tickableInstances.clear(); - dynamicInstances.clear(); + public int getInstanceCount() { + return instances.size(); } @Override @@ -75,9 +64,8 @@ public class EffectInstanceManager extends InstanceManager { this.tickableInstances.removeAll(instances); this.dynamicInstances.removeAll(instances); - for (AbstractInstance instance : instances) { - LightUpdater.get(instance.level) - .removeListener(instance); + for (Instance instance : instances) { + instance.removeNow(); } } @@ -89,20 +77,28 @@ public class EffectInstanceManager extends InstanceManager { return; } - instances.forEach(AbstractInstance::update); + instances.forEach(Instance::update); } @Override public void recreateAll() { - this.dynamicInstances.clear(); - this.tickableInstances.clear(); - this.instances.values().forEach(AbstractInstance::removeAndMark); + tickableInstances.clear(); + dynamicInstances.clear(); + instances.values().forEach(Instance::delete); - var backup = new ArrayList<>(this.instances.keySet()); - this.instances.clear(); + var backup = new ArrayList<>(instances.keySet()); + instances.clear(); backup.forEach(this::create); } + @Override + public void invalidate() { + instances.values().forEach(Instance::delete); + instances.clear(); + tickableInstances.clear(); + dynamicInstances.clear(); + } + private void create(T obj) { var instances = obj.createInstances(instancerManager); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java new file mode 100644 index 000000000..db513a79b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java @@ -0,0 +1,53 @@ +package com.jozufozu.flywheel.backend.instancing.manager; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instancer.InstancerProvider; +import com.jozufozu.flywheel.backend.BackendUtil; +import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage; +import com.jozufozu.flywheel.backend.instancing.storage.Storage; +import com.jozufozu.flywheel.lib.instance.InstancingControllerHelper; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; + +public class EntityInstanceManager extends InstanceManager { + private final EntityStorage storage; + + public EntityInstanceManager(InstancerProvider instancerManager) { + storage = new EntityStorage(instancerManager); + } + + @Override + protected Storage getStorage() { + return storage; + } + + @Override + protected boolean canCreateInstance(Entity entity) { + if (!entity.isAlive()) { + return false; + } + + if (!InstancingControllerHelper.canInstance(entity.getType())) { + return false; + } + + Level level = entity.level; + + return BackendUtil.isFlywheelLevel(level); + } + + private static class EntityStorage extends One2OneStorage { + public EntityStorage(InstancerProvider instancerManager) { + super(instancerManager); + } + + @Override + @Nullable + protected Instance createRaw(Entity obj) { + return InstancingControllerHelper.createInstance(instancerManager, obj); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/InstanceManager.java similarity index 82% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/manager/InstanceManager.java index 77cfe6e41..e4f45996c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/InstanceManager.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.instancing; +package com.jozufozu.flywheel.backend.instancing.manager; import java.util.ArrayList; import java.util.Collection; @@ -12,6 +12,7 @@ import org.joml.FrustumIntersection; import com.jozufozu.flywheel.api.backend.BackendManager; import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.task.TaskExecutor; import com.jozufozu.flywheel.backend.instancing.ratelimit.BandedPrimeLimiter; @@ -19,33 +20,28 @@ import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter; import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter; import com.jozufozu.flywheel.backend.instancing.storage.Storage; import com.jozufozu.flywheel.config.FlwConfig; -import com.jozufozu.flywheel.lib.light.LightUpdater; import net.minecraft.core.BlockPos; public abstract class InstanceManager { + private final Set queuedAdditions = new HashSet<>(64); + private final Set queuedUpdates = new HashSet<>(64); - private final Set queuedAdditions; - private final Set queuedUpdates; - - protected DistanceUpdateLimiter frame; - protected DistanceUpdateLimiter tick; + protected DistanceUpdateLimiter frameLimiter; + protected DistanceUpdateLimiter tickLimiter; public InstanceManager() { - this.queuedUpdates = new HashSet<>(64); - this.queuedAdditions = new HashSet<>(64); - - frame = createUpdateLimiter(); - tick = createUpdateLimiter(); + frameLimiter = createUpdateLimiter(); + tickLimiter = createUpdateLimiter(); } - public abstract Storage getStorage(); + protected abstract Storage getStorage(); /** * Is the given object currently capable of being instanced? * *

    - * This won't be the case for TEs or entities that are outside of loaded chunks. + * This won't be the case for block entities or entities that are outside of loaded chunks. *

    * * @return true if the object is currently capable of being instanced. @@ -65,102 +61,8 @@ public abstract class InstanceManager { * * @return The object count. */ - public int getObjectCount() { - return getStorage().getObjectCount(); - } - - /** - * Ticks the InstanceManager. - * - *

    - * {@link TickableInstance}s get ticked. - *
    - * Queued updates are processed. - *

    - */ - public void tick(TaskExecutor executor, double cameraX, double cameraY, double cameraZ) { - tick.tick(); - processQueuedUpdates(); - - // integer camera pos as a micro-optimization - int cX = (int) cameraX; - int cY = (int) cameraY; - int cZ = (int) cameraZ; - - var instances = getStorage().getInstancesForTicking(); - distributeWork(executor, instances, instance -> tickInstance(instance, cX, cY, cZ)); - } - - protected void tickInstance(TickableInstance instance, int cX, int cY, int cZ) { - if (!instance.decreaseTickRateWithDistance()) { - instance.tick(); - return; - } - - BlockPos pos = instance.getWorldPosition(); - - int dX = pos.getX() - cX; - int dY = pos.getY() - cY; - int dZ = pos.getZ() - cZ; - - if (!tick.shouldUpdate(dX, dY, dZ)) { - return; - } - - instance.tick(); - } - - public void beginFrame(TaskExecutor executor, RenderContext context) { - frame.tick(); - processQueuedAdditions(); - - // integer camera pos - BlockPos cameraIntPos = context.camera().getBlockPosition(); - int cX = cameraIntPos.getX(); - int cY = cameraIntPos.getY(); - int cZ = cameraIntPos.getZ(); - FrustumIntersection culler = context.culler(); - - var instances = getStorage().getInstancesForUpdate(); - distributeWork(executor, instances, instance -> updateInstance(instance, culler, cX, cY, cZ)); - } - - private static void distributeWork(TaskExecutor executor, List instances, Consumer action) { - final int size = instances.size(); - final int threadCount = executor.getThreadCount(); - - if (threadCount == 1) { - executor.execute(() -> instances.forEach(action)); - } else { - final int stride = Math.max(size / (threadCount * 2), 1); - for (int start = 0; start < size; start += stride) { - int end = Math.min(start + stride, size); - - var sub = instances.subList(start, end); - executor.execute(() -> sub.forEach(action)); - } - } - } - - protected void updateInstance(DynamicInstance dyn, FrustumIntersection test, int cX, int cY, int cZ) { - if (!dyn.decreaseFramerateWithDistance()) { - dyn.beginFrame(); - return; - } - - BlockPos worldPos = dyn.getWorldPosition(); - int dX = worldPos.getX() - cX; - int dY = worldPos.getY() - cY; - int dZ = worldPos.getZ() - cZ; - - if (!frame.shouldUpdate(dX, dY, dZ)) { - return; - } - - if (dyn.checkFrustum(test)) { - dyn.beginFrame(); - } - + public int getInstanceCount() { + return getStorage().getInstanceCount(); } public void add(T obj) { @@ -185,15 +87,13 @@ public abstract class InstanceManager { } } - public void queueUpdate(T obj) { - if (!BackendManager.isOn()) return; - - if (!canCreateInstance(obj)) { + public void queueAddAll(Collection objects) { + if (!BackendManager.isOn() || objects.isEmpty()) { return; } - synchronized (queuedUpdates) { - queuedUpdates.add(obj); + synchronized (queuedAdditions) { + queuedAdditions.addAll(objects); } } @@ -216,16 +116,38 @@ public abstract class InstanceManager { } } + public void queueUpdate(T obj) { + if (!BackendManager.isOn()) return; + + if (!canCreateInstance(obj)) { + return; + } + + synchronized (queuedUpdates) { + queuedUpdates.add(obj); + } + } + public void remove(T obj) { if (!BackendManager.isOn()) return; getStorage().remove(obj); } + public void onOriginShift() { + getStorage().recreateAll(); + } + public void invalidate() { getStorage().invalidate(); } + public void delete() { + for (Instance instance : getStorage().getAllInstances()) { + instance.removeNow(); + } + } + protected void processQueuedAdditions() { if (queuedAdditions.isEmpty()) { return; @@ -256,23 +178,96 @@ public abstract class InstanceManager { } } - public void onOriginShift() { - getStorage().recreateAll(); + /** + * Ticks the InstanceManager. + * + *

    + * {@link TickableInstance}s get ticked. + *
    + * Queued updates are processed. + *

    + */ + public void tick(TaskExecutor executor, double cameraX, double cameraY, double cameraZ) { + tickLimiter.tick(); + processQueuedUpdates(); + + // integer camera pos as a micro-optimization + int cX = (int) cameraX; + int cY = (int) cameraY; + int cZ = (int) cameraZ; + + var instances = getStorage().getInstancesForTicking(); + distributeWork(executor, instances, instance -> tickInstance(instance, cX, cY, cZ)); } - public void delete() { - for (AbstractInstance value : getStorage().allInstances()) { - LightUpdater.get(value.level).removeListener(value); - } - } - - public void queueAddAll(Collection objects) { - if (!BackendManager.isOn() || objects.isEmpty()) { + protected void tickInstance(TickableInstance instance, int cX, int cY, int cZ) { + if (!instance.decreaseTickRateWithDistance()) { + instance.tick(); return; } - synchronized (queuedAdditions) { - queuedAdditions.addAll(objects); + BlockPos pos = instance.getWorldPosition(); + + int dX = pos.getX() - cX; + int dY = pos.getY() - cY; + int dZ = pos.getZ() - cZ; + + if (!tickLimiter.shouldUpdate(dX, dY, dZ)) { + return; + } + + instance.tick(); + } + + public void beginFrame(TaskExecutor executor, RenderContext context) { + frameLimiter.tick(); + processQueuedAdditions(); + + // integer camera pos + BlockPos cameraIntPos = context.camera().getBlockPosition(); + int cX = cameraIntPos.getX(); + int cY = cameraIntPos.getY(); + int cZ = cameraIntPos.getZ(); + FrustumIntersection culler = context.culler(); + + var instances = getStorage().getInstancesForUpdate(); + distributeWork(executor, instances, instance -> updateInstance(instance, culler, cX, cY, cZ)); + } + + private static void distributeWork(TaskExecutor executor, List instances, Consumer action) { + final int size = instances.size(); + final int threadCount = executor.getThreadCount(); + + if (threadCount == 1) { + executor.execute(() -> instances.forEach(action)); + } else { + final int stride = Math.max(size / (threadCount * 2), 1); + for (int start = 0; start < size; start += stride) { + int end = Math.min(start + stride, size); + + var sub = instances.subList(start, end); + executor.execute(() -> sub.forEach(action)); + } + } + } + + protected void updateInstance(DynamicInstance instance, FrustumIntersection frustum, int cX, int cY, int cZ) { + if (!instance.decreaseFramerateWithDistance()) { + instance.beginFrame(); + return; + } + + BlockPos worldPos = instance.getWorldPosition(); + int dX = worldPos.getX() - cX; + int dY = worldPos.getY() - cY; + int dZ = worldPos.getZ() - cZ; + + if (!frameLimiter.shouldUpdate(dX, dY, dZ)) { + return; + } + + if (instance.checkFrustum(frustum)) { + instance.beginFrame(); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java index 278f5ff1e..18d740814 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java @@ -4,7 +4,7 @@ import net.minecraft.util.Mth; public class BandedPrimeLimiter implements DistanceUpdateLimiter { // 1 followed by the prime numbers - private static final int[] divisorSequence = new int[] { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 }; + private static final int[] DIVISOR_SEQUENCE = new int[] { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 }; private int tickCount = 0; @@ -23,6 +23,6 @@ public class BandedPrimeLimiter implements DistanceUpdateLimiter { int i = (dSq / 2048); - return divisorSequence[Mth.clamp(i, 0, divisorSequence.length - 1)]; + return DIVISOR_SEQUENCE[Mth.clamp(i, 0, DIVISOR_SEQUENCE.length - 1)]; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java index ea5afb230..e13d742b1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing.ratelimit; public class NonLimiter implements DistanceUpdateLimiter { @Override public void tick() { - // noop } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java index f2274b4da..42daba0d4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java @@ -4,21 +4,17 @@ import java.util.ArrayList; import java.util.List; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.lib.light.LightUpdater; public abstract class AbstractStorage implements Storage { - protected final List tickableInstances; - protected final List dynamicInstances; protected final InstancerProvider instancerManager; + protected final List tickableInstances = new ArrayList<>(); + protected final List dynamicInstances = new ArrayList<>(); protected AbstractStorage(InstancerProvider instancerManager) { this.instancerManager = instancerManager; - - this.dynamicInstances = new ArrayList<>(); - this.tickableInstances = new ArrayList<>(); } @Override @@ -31,19 +27,17 @@ public abstract class AbstractStorage implements Storage { return dynamicInstances; } - protected void setup(AbstractInstance renderer) { - renderer.init(); - renderer.updateLight(); - LightUpdater.get(renderer.level) - .addListener(renderer); - if (renderer instanceof TickableInstance r) { - tickableInstances.add(r); - r.tick(); + protected void setup(Instance instance) { + instance.init(); + + if (instance instanceof TickableInstance tickable) { + tickableInstances.add(tickable); + tickable.tick(); } - if (renderer instanceof DynamicInstance r) { - dynamicInstances.add(r); - r.beginFrame(); + if (instance instanceof DynamicInstance dynamic) { + dynamicInstances.add(dynamic); + dynamic.beginFrame(); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java index 2ca0866cb..af3f29290 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java @@ -5,12 +5,11 @@ import java.util.Map; import org.jetbrains.annotations.Nullable; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.lib.light.LightUpdater; public abstract class One2OneStorage extends AbstractStorage { - private final Map instances; + private final Map instances; public One2OneStorage(InstancerProvider instancerManager) { super(instancerManager); @@ -18,26 +17,18 @@ public abstract class One2OneStorage extends AbstractStorage { } @Override - public int getObjectCount() { - return instances.size(); - } - - @Override - public Iterable allInstances() { + public Iterable getAllInstances() { return instances.values(); } @Override - public void invalidate() { - instances.values().forEach(AbstractInstance::remove); - instances.clear(); - dynamicInstances.clear(); - tickableInstances.clear(); + public int getInstanceCount() { + return instances.size(); } @Override public void add(T obj) { - AbstractInstance instance = instances.get(obj); + Instance instance = instances.get(obj); if (instance == null) { create(obj); @@ -46,22 +37,21 @@ public abstract class One2OneStorage extends AbstractStorage { @Override public void remove(T obj) { - var instance = instances.remove(obj); + Instance instance = instances.remove(obj); if (instance == null) { return; } - instance.remove(); + instance.delete(); dynamicInstances.remove(instance); tickableInstances.remove(instance); - LightUpdater.get(instance.level) - .removeListener(instance); + instance.removeNow(); } @Override public void update(T obj) { - AbstractInstance instance = instances.get(obj); + Instance instance = instances.get(obj); if (instance == null) { return; @@ -83,9 +73,9 @@ public abstract class One2OneStorage extends AbstractStorage { dynamicInstances.clear(); tickableInstances.clear(); instances.replaceAll((obj, instance) -> { - instance.remove(); + instance.delete(); - AbstractInstance out = createRaw(obj); + Instance out = createRaw(obj); if (out != null) { setup(out); @@ -95,16 +85,23 @@ public abstract class One2OneStorage extends AbstractStorage { }); } + @Override + public void invalidate() { + instances.values().forEach(Instance::delete); + instances.clear(); + tickableInstances.clear(); + dynamicInstances.clear(); + } + private void create(T obj) { - AbstractInstance renderer = createRaw(obj); + Instance instance = createRaw(obj); - if (renderer != null) { - setup(renderer); - instances.put(obj, renderer); + if (instance != null) { + setup(instance); + instances.put(obj, instance); } - } @Nullable - protected abstract AbstractInstance createRaw(T obj); + protected abstract Instance createRaw(T obj); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/Storage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/Storage.java index 0f6bd278c..a182f3d11 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/Storage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/Storage.java @@ -3,20 +3,18 @@ package com.jozufozu.flywheel.backend.instancing.storage; import java.util.List; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; public interface Storage { - int getObjectCount(); + Iterable getAllInstances(); - Iterable allInstances(); + int getInstanceCount(); List getInstancesForTicking(); List getInstancesForUpdate(); - void invalidate(); - void add(T obj); void remove(T obj); @@ -24,4 +22,6 @@ public interface Storage { void update(T obj); void recreateAll(); + + void invalidate(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/task/SerialTaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/task/SerialTaskExecutor.java index dc2fd905c..6e273ab1b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/task/SerialTaskExecutor.java +++ b/src/main/java/com/jozufozu/flywheel/backend/task/SerialTaskExecutor.java @@ -15,7 +15,6 @@ public class SerialTaskExecutor implements TaskExecutor { @Override public void syncPoint() { - // noop } @Override diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index cca4aae70..c003db08a 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -63,7 +63,7 @@ public class FlwCommands { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { Backend backend = context.getArgument("id", Backend.class); - value.set(Backend.REGISTRY.getId(backend).toString()); + value.set(Backend.REGISTRY.getIdOrThrow(backend).toString()); Component message = backend.getEngineMessage(); player.displayClientMessage(message, false); diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java index 3652461c1..8dc6cb603 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java @@ -24,10 +24,9 @@ public class FlwConfig { private final ForgeConfigSpec clientSpec; public FlwConfig() { - Pair client = new ForgeConfigSpec.Builder().configure(ClientConfig::new); - - this.client = client.getLeft(); - clientSpec = client.getRight(); + Pair clientPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new); + this.client = clientPair.getLeft(); + clientSpec = clientPair.getRight(); } public static FlwConfig get() { @@ -38,7 +37,7 @@ public class FlwConfig { Backend backend = parseBackend(client.backend.get()); if (backend == null) { backend = BackendManager.getDefaultBackend(); - client.backend.set(Backend.REGISTRY.getId(backend).toString()); + client.backend.set(Backend.REGISTRY.getIdOrThrow(backend).toString()); } return backend; @@ -77,7 +76,7 @@ public class FlwConfig { public ClientConfig(ForgeConfigSpec.Builder builder) { backend = builder.comment("Select the backend to use.") - .define("backend", Backend.REGISTRY.getId(BackendManager.getDefaultBackend()).toString()); + .define("backend", Backend.REGISTRY.getIdOrThrow(BackendManager.getDefaultBackend()).toString()); limitUpdates = builder.comment("Enable or disable instance update limiting with distance.") .define("limitUpdates", true); diff --git a/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java index 2eba7485e..65f6b63f5 100644 --- a/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java +++ b/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java @@ -2,7 +2,7 @@ package com.jozufozu.flywheel.extension; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java index 28427dd51..0bce72734 100644 --- a/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java +++ b/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java @@ -2,7 +2,7 @@ package com.jozufozu.flywheel.extension; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; import net.minecraft.world.entity.Entity; diff --git a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java index a1bee4e39..5d7245800 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java @@ -39,7 +39,7 @@ public final class BackendManagerImpl { var actual = preferred.findFallback(); if (preferred != actual) { - LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", Backend.REGISTRY.getId(preferred), Backend.REGISTRY.getId(actual)); + LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", Backend.REGISTRY.getIdOrThrow(preferred), Backend.REGISTRY.getIdOrThrow(actual)); } return actual; diff --git a/src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java b/src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java index 0493e402f..b7c3b6f25 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java @@ -72,6 +72,24 @@ public class IdRegistryImpl implements IdRegistry { return reverseMap.get(object); } + @Override + public T getOrThrow(ResourceLocation id) { + T object = get(id); + if (object == null) { + throw new IllegalArgumentException("Could not find object for ID '" + id + "'!"); + } + return object; + } + + @Override + public ResourceLocation getIdOrThrow(T object) { + ResourceLocation id = getId(object); + if (id == null) { + throw new IllegalArgumentException("Could not find ID for object!"); + } + return id; + } + @Override @Unmodifiable public Set getAllIds() { @@ -107,6 +125,7 @@ public class IdRegistryImpl implements IdRegistry { for (Runnable runnable : freezeCallbacks) { runnable.run(); } + freezeCallbacks.clear(); } public static void freezeAll() { diff --git a/src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java b/src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java index 4e7a8b1c5..9e9ae7656 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java @@ -91,6 +91,7 @@ public class RegistryImpl implements Registry { for (Runnable runnable : freezeCallbacks) { runnable.run(); } + freezeCallbacks.clear(); } public static void freezeAll() { diff --git a/src/main/java/com/jozufozu/flywheel/impl/instance/InstancingControllerRegistryImpl.java b/src/main/java/com/jozufozu/flywheel/impl/instance/InstancingControllerRegistryImpl.java new file mode 100644 index 000000000..0febe856f --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/instance/InstancingControllerRegistryImpl.java @@ -0,0 +1,37 @@ +package com.jozufozu.flywheel.impl.instance; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; +import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; +import com.jozufozu.flywheel.extension.EntityTypeExtension; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +@SuppressWarnings("unchecked") +public final class InstancingControllerRegistryImpl { + @Nullable + public static BlockEntityInstancingController getController(BlockEntityType type) { + return ((BlockEntityTypeExtension) type).flywheel$getInstancingController(); + } + + @Nullable + public static EntityInstancingController getController(EntityType type) { + return ((EntityTypeExtension) type).flywheel$getInstancingController(); + } + + public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { + ((BlockEntityTypeExtension) type).flywheel$setInstancingController(instancingController); + } + + public static void setController(EntityType type, EntityInstancingController instancingController) { + ((EntityTypeExtension) type).flywheel$setInstancingController(instancingController); + } + + private InstancingControllerRegistryImpl() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java similarity index 85% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java index 128cbfa20..402b57004 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java @@ -1,15 +1,16 @@ -package com.jozufozu.flywheel.backend.instancing.blockentity; +package com.jozufozu.flywheel.lib.instance; import java.util.ArrayList; import java.util.List; import org.joml.FrustumIntersection; +import com.jozufozu.flywheel.api.instance.BlockEntityInstance; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; +import com.jozufozu.flywheel.backend.instancing.manager.BlockEntityInstanceManager; import com.jozufozu.flywheel.lib.box.ImmutableBox; import com.jozufozu.flywheel.lib.box.MutableBox; @@ -29,19 +30,19 @@ import net.minecraft.world.level.block.state.BlockState; *
* See the interfaces' documentation for more information about each one. * - *
Implementing one or more of these will give a {@link BlockEntityInstance} access + *
Implementing one or more of these will give a {@link AbstractBlockEntityInstance} access * to more interesting and regular points within a tick or a frame. * * @param The type of {@link BlockEntity} your class is an instance of. */ -public abstract class BlockEntityInstance extends AbstractInstance { +public abstract class AbstractBlockEntityInstance extends AbstractInstance implements BlockEntityInstance { protected final T blockEntity; protected final BlockPos pos; protected final BlockPos instancePos; protected final BlockState blockState; - public BlockEntityInstance(InstancerProvider instancerManager, T blockEntity) { + public AbstractBlockEntityInstance(InstancerProvider instancerManager, T blockEntity) { super(instancerManager, blockEntity.getLevel()); this.blockEntity = blockEntity; this.pos = blockEntity.getBlockPos(); @@ -49,6 +50,7 @@ public abstract class BlockEntityInstance extends Abstrac this.instancePos = pos.subtract(instancerManager.getOriginCoordinate()); } + @Override public List getCrumblingParts() { var out = new ArrayList(); addCrumblingParts(out); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java similarity index 85% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java index 58e6f2737..ca4fc8179 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java @@ -1,14 +1,13 @@ -package com.jozufozu.flywheel.backend.instancing.entity; +package com.jozufozu.flywheel.lib.instance; import org.joml.FrustumIntersection; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.EntityInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.manager.BlockEntityInstanceManager; import com.jozufozu.flywheel.lib.box.MutableBox; -import com.jozufozu.flywheel.lib.light.LightListener; import com.jozufozu.flywheel.lib.light.TickingLightListener; import com.mojang.math.Vector3f; @@ -30,17 +29,17 @@ import net.minecraft.world.phys.Vec3; * * See the interfaces' documentation for more information about each one. * - *
Implementing one or more of these will give a {@link EntityInstance} access + *
Implementing one or more of these will give a {@link AbstractEntityInstance} access * to more interesting and regular points within a tick or a frame. * * @param The type of {@link Entity} your class is an instance of. */ -public abstract class EntityInstance extends AbstractInstance implements LightListener, TickingLightListener { +public abstract class AbstractEntityInstance extends AbstractInstance implements EntityInstance, TickingLightListener { protected final E entity; protected final MutableBox bounds; - public EntityInstance(InstancerProvider instancerManager, E entity) { + public AbstractEntityInstance(InstancerProvider instancerManager, E entity) { super(instancerManager, entity.level); this.entity = entity; bounds = MutableBox.from(entity.getBoundingBox()); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java similarity index 52% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java index 610f6335f..2f22bb5b6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java @@ -1,66 +1,44 @@ -package com.jozufozu.flywheel.backend.instancing; +package com.jozufozu.flywheel.lib.instance; import java.util.Arrays; import java.util.stream.Stream; -import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.FlatLit; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.lib.light.LightListener; +import com.jozufozu.flywheel.lib.light.LightUpdater; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.LightLayer; -/** - * A general interface providing information about any type of thing that could use Flywheel's instanced rendering. - * Right now, that's only {@link BlockEntityInstanceManager}, but there could be an entity equivalent in the future. - */ public abstract class AbstractInstance implements Instance, LightListener { - protected final InstancerProvider instancerManager; public final Level level; - protected boolean removed = false; + protected boolean deleted = false; public AbstractInstance(InstancerProvider instancerManager, Level level) { this.instancerManager = instancerManager; this.level = level; } - /** - * Initialize models here. - */ + @Override public void init() { - + updateLight(); + LightUpdater.get(level).addListener(this); } - public final void removeAndMark() { - if (removed) { - return; - } - - remove(); - removed = true; - } - - /** - * Free any acquired resources. - */ - public abstract void remove(); - - /** - * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. - * Don't query lighting data here, that's handled separately in {@link #updateLight()}. - * - *

If your animations are complex or more CPU driven, see {@link DynamicInstance} or {@link TickableInstance}. - */ + @Override public void update() { } + @Override + public boolean shouldReset() { + return false; + } + /** * Called after construction and when a light update occurs in the world. * @@ -69,30 +47,21 @@ public abstract class AbstractInstance implements Instance, LightListener { public void updateLight() { } - /** - * When an instance is reset, the instance is deleted and re-created. - * - *

- * Just before {@link #update()} would be called, {@code shouldReset()} is checked. - * If this function returns {@code true}, then this instance will be {@link #remove removed}, - * and another instance will be constructed to replace it. This allows for more sane resource - * acquisition compared to trying to update everything within the lifetime of an instance. - *

- * - * @return {@code true} if this instance should be discarded and refreshed. - */ - public boolean shouldReset() { - return false; + protected abstract void _delete(); + + @Override + public final void delete() { + if (deleted) { + return; + } + + _delete(); + deleted = true; } @Override public boolean isInvalid() { - return removed; - } - - @Override - public boolean isRemoved() { - return removed; + return deleted; } @Override @@ -117,4 +86,8 @@ public abstract class AbstractInstance implements Instance, LightListener { .setSkyLight(sky)); } + @Override + public final void removeNow() { + LightUpdater.get(level).removeListener(this); + } } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstancedRenderRegistry.java b/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java similarity index 54% rename from src/main/java/com/jozufozu/flywheel/api/instance/InstancedRenderRegistry.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java index 92b5bd487..57fb789de 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/InstancedRenderRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java @@ -1,25 +1,20 @@ -package com.jozufozu.flywheel.api.instance; +package com.jozufozu.flywheel.lib.instance; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController; -import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.BlockEntityInstance; +import com.jozufozu.flywheel.api.instance.EntityInstance; +import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; -import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; -import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; -import com.jozufozu.flywheel.extension.EntityTypeExtension; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; -/** - * A utility class for registering and retrieving {@code InstancingController}s. - */ -@SuppressWarnings("unchecked") -public class InstancedRenderRegistry { +public final class InstancingControllerHelper { /** * Checks if the given block entity type can be instanced. * @param type The block entity type to check. @@ -27,7 +22,7 @@ public class InstancedRenderRegistry { * @return {@code true} if the block entity type can be instanced. */ public static boolean canInstance(BlockEntityType type) { - return getController(type) != null; + return InstancingControllerRegistry.getController(type) != null; } /** @@ -37,7 +32,7 @@ public class InstancedRenderRegistry { * @return {@code true} if the entity type can be instanced. */ public static boolean canInstance(EntityType type) { - return getController(type) != null; + return InstancingControllerRegistry.getController(type) != null; } /** @@ -49,7 +44,7 @@ public class InstancedRenderRegistry { */ @Nullable public static BlockEntityInstance createInstance(InstancerProvider instancerManager, T blockEntity) { - BlockEntityInstancingController controller = getController(getType(blockEntity)); + BlockEntityInstancingController controller = InstancingControllerRegistry.getController(getType(blockEntity)); if (controller == null) { return null; } @@ -65,7 +60,7 @@ public class InstancedRenderRegistry { */ @Nullable public static EntityInstance createInstance(InstancerProvider instancerManager, T entity) { - EntityInstancingController controller = getController(getType(entity)); + EntityInstancingController controller = InstancingControllerRegistry.getController(getType(entity)); if (controller == null) { return null; } @@ -79,7 +74,7 @@ public class InstancedRenderRegistry { * @return {@code true} if the block entity is instanced and should not be rendered normally. */ public static boolean shouldSkipRender(T blockEntity) { - BlockEntityInstancingController controller = getController(getType(blockEntity)); + BlockEntityInstancingController controller = InstancingControllerRegistry.getController(getType(blockEntity)); if (controller == null) { return false; } @@ -93,61 +88,20 @@ public class InstancedRenderRegistry { * @return {@code true} if the entity is instanced and should not be rendered normally. */ public static boolean shouldSkipRender(T entity) { - EntityInstancingController controller = getController(getType(entity)); + EntityInstancingController controller = InstancingControllerRegistry.getController(getType(entity)); if (controller == null) { return false; } return controller.shouldSkipRender(entity); } - /** - * Gets the instancing controller for the given block entity type, if one exists. - * @param type The block entity type to get the instancing controller for. - * @param The type of the block entity. - * @return The instancing controller for the given block entity type, or {@code null} if none exists. - */ - @Nullable - public static BlockEntityInstancingController getController(BlockEntityType type) { - return ((BlockEntityTypeExtension) type).flywheel$getInstancingController(); - } - - /** - * Gets the instancing controller for the given entity type, if one exists. - * @param type The entity type to get the instancing controller for. - * @param The type of the entity. - * @return The instancing controller for the given entity type, or {@code null} if none exists. - */ - @Nullable - public static EntityInstancingController getController(EntityType type) { - return ((EntityTypeExtension) type).flywheel$getInstancingController(); - } - - /** - * Sets the instancing controller for the given block entity type. - * @param type The block entity type to set the instancing controller for. - * @param instancingController The instancing controller to set. - * @param The type of the block entity. - */ - public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { - ((BlockEntityTypeExtension) type).flywheel$setInstancingController(instancingController); - } - - /** - * Sets the instancing controller for the given entity type. - * @param type The entity type to set the instancing controller for. - * @param instancingController The instancing controller to set. - * @param The type of the entity. - */ - public static void setController(EntityType type, EntityInstancingController instancingController) { - ((EntityTypeExtension) type).flywheel$setInstancingController(instancingController); - } - /** * Gets the type of the given block entity. * @param blockEntity The block entity to get the type of. * @param The type of the block entity. * @return The {@link BlockEntityType} associated with the given block entity. */ + @SuppressWarnings("unchecked") public static BlockEntityType getType(T blockEntity) { return (BlockEntityType) blockEntity.getType(); } @@ -158,7 +112,11 @@ public class InstancedRenderRegistry { * @param The type of the entity. * @return The {@link EntityType} associated with the given entity. */ + @SuppressWarnings("unchecked") public static EntityType getType(T entity) { return (EntityType) entity.getType(); } + + private InstancingControllerHelper() { + } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java index 99ee6b54f..3a03e7f2c 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java @@ -4,10 +4,10 @@ import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Predicate; -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; -import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.BlockEntityInstance; +import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -93,7 +93,7 @@ public class SimpleBlockEntityInstancingController implem skipRender = be -> false; } SimpleBlockEntityInstancingController controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender); - InstancedRenderRegistry.setController(type, controller); + InstancingControllerRegistry.setController(type, controller); return controller; } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java index 780b18048..b65025165 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java @@ -4,10 +4,10 @@ import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Predicate; -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; -import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.EntityInstance; +import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -93,7 +93,7 @@ public class SimpleEntityInstancingController implements Entit skipRender = entity -> false; } SimpleEntityInstancingController controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender); - InstancedRenderRegistry.setController(type, controller); + InstancingControllerRegistry.setController(type, controller); return controller; } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndicies.java b/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java similarity index 71% rename from src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndicies.java rename to src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java index 74d33d46a..78a619dda 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndicies.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java @@ -21,10 +21,10 @@ import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; import net.minecraft.resources.ResourceLocation; // TODO: add messages to exceptions -public class MaterialIndicies { - private static Reference2IntMap materialIndicies; - private static Object2IntMap vertexShaderIndicies; - private static Object2IntMap fragmentShaderIndicies; +public class MaterialIndices { + private static Reference2IntMap materialIndices; + private static Object2IntMap vertexShaderIndices; + private static Object2IntMap fragmentShaderIndices; private static ObjectList materialsByIndex; private static ObjectList vertexShadersByIndex; private static ObjectList fragmentShadersByIndex; @@ -34,21 +34,29 @@ public class MaterialIndicies { if (!initialized) { throw new IllegalStateException(); } - return materialIndicies.getInt(material); + return materialIndices.getInt(material); } public static int getVertexShaderIndex(ResourceLocation vertexShader) { if (!initialized) { throw new IllegalStateException(); } - return vertexShaderIndicies.getInt(vertexShader); + return vertexShaderIndices.getInt(vertexShader); } public static int getFragmentShaderIndex(ResourceLocation fragmentShader) { if (!initialized) { throw new IllegalStateException(); } - return fragmentShaderIndicies.getInt(fragmentShader); + return fragmentShaderIndices.getInt(fragmentShader); + } + + public static int getVertexShaderIndex(Material material) { + return getVertexShaderIndex(material.vertexShader()); + } + + public static int getFragmentShaderIndex(Material material) { + return getFragmentShaderIndex(material.fragmentShader()); } public static Material getMaterial(int index) { @@ -99,9 +107,9 @@ public class MaterialIndicies { private static void initInner() { int amount = Material.REGISTRY.getAll().size(); - Reference2IntMap materialIndicies = new Reference2IntOpenHashMap<>(); - Object2IntMap vertexShaderIndicies = new Object2IntOpenHashMap<>(); - Object2IntMap fragmentShaderIndicies = new Object2IntOpenHashMap<>(); + Reference2IntMap materialIndices = new Reference2IntOpenHashMap<>(); + Object2IntMap vertexShaderIndices = new Object2IntOpenHashMap<>(); + Object2IntMap fragmentShaderIndices = new Object2IntOpenHashMap<>(); ObjectList materialsByIndex = new ObjectArrayList<>(amount); ObjectList vertexShadersByIndex = new ObjectArrayList<>(amount); ObjectList fragmentShadersByIndex = new ObjectArrayList<>(amount); @@ -113,35 +121,35 @@ public class MaterialIndicies { int vertexShaderIndex = 0; int fragmentShaderIndex = 0; for (Material material : Material.REGISTRY) { - materialIndicies.put(material, materialIndex); + materialIndices.put(material, materialIndex); materialsByIndex.add(material); materialIndex++; ResourceLocation vertexShader = material.vertexShader(); if (allVertexShaders.add(vertexShader)) { - vertexShaderIndicies.put(vertexShader, vertexShaderIndex); + vertexShaderIndices.put(vertexShader, vertexShaderIndex); vertexShadersByIndex.add(vertexShader); vertexShaderIndex++; } ResourceLocation fragmentShader = material.fragmentShader(); if (allFragmentShaders.add(fragmentShader)) { - fragmentShaderIndicies.put(fragmentShader, fragmentShaderIndex); + fragmentShaderIndices.put(fragmentShader, fragmentShaderIndex); fragmentShadersByIndex.add(fragmentShader); fragmentShaderIndex++; } } - MaterialIndicies.materialIndicies = Reference2IntMaps.unmodifiable(materialIndicies); - MaterialIndicies.vertexShaderIndicies = Object2IntMaps.unmodifiable(vertexShaderIndicies); - MaterialIndicies.fragmentShaderIndicies = Object2IntMaps.unmodifiable(fragmentShaderIndicies); - MaterialIndicies.materialsByIndex = ObjectLists.unmodifiable(materialsByIndex); - MaterialIndicies.vertexShadersByIndex = ObjectLists.unmodifiable(vertexShadersByIndex); - MaterialIndicies.fragmentShadersByIndex = ObjectLists.unmodifiable(fragmentShadersByIndex); + MaterialIndices.materialIndices = Reference2IntMaps.unmodifiable(materialIndices); + MaterialIndices.vertexShaderIndices = Object2IntMaps.unmodifiable(vertexShaderIndices); + MaterialIndices.fragmentShaderIndices = Object2IntMaps.unmodifiable(fragmentShaderIndices); + MaterialIndices.materialsByIndex = ObjectLists.unmodifiable(materialsByIndex); + MaterialIndices.vertexShadersByIndex = ObjectLists.unmodifiable(vertexShadersByIndex); + MaterialIndices.fragmentShadersByIndex = ObjectLists.unmodifiable(fragmentShadersByIndex); initialized = true; } @ApiStatus.Internal public static void init() { - Material.REGISTRY.addFreezeCallback(MaterialIndicies::initInner); + Material.REGISTRY.addFreezeCallback(MaterialIndices::initInner); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java index 6f54f1ee9..6626815be 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java index 51565452e..ddfa8c0c3 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java @@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.google.common.collect.Lists; import com.jozufozu.flywheel.api.backend.BackendManager; -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; import com.jozufozu.flywheel.extension.ClientLevelExtension; +import com.jozufozu.flywheel.lib.instance.InstancingControllerHelper; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.world.entity.Entity; @@ -33,7 +33,7 @@ public abstract class ClientLevelMixin implements ClientLevelExtension { Iterable entities = cir.getReturnValue(); ArrayList filtered = Lists.newArrayList(entities); - filtered.removeIf(InstancedRenderRegistry::shouldSkipRender); + filtered.removeIf(InstancingControllerHelper::shouldSkipRender); cir.setReturnValue(filtered); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java index e19a4fca9..c20cabb6d 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController; +import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; import com.jozufozu.flywheel.extension.EntityTypeExtension; import net.minecraft.world.entity.Entity; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java index 64cd248e8..c81db100b 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java @@ -7,9 +7,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry; import com.jozufozu.flywheel.backend.BackendUtil; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.lib.instance.InstancingControllerHelper; import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; import net.minecraft.world.level.block.entity.BlockEntity; @@ -19,10 +19,10 @@ public class ChunkRebuildHooksMixin { @Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true) private void flywheel$addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set set, E be, CallbackInfo ci) { if (BackendUtil.canUseInstancing(be.getLevel())) { - if (InstancedRenderRegistry.canInstance(be.getType())) + if (InstancingControllerHelper.canInstance(be.getType())) InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be); - if (InstancedRenderRegistry.shouldSkipRender(be)) + if (InstancingControllerHelper.shouldSkipRender(be)) ci.cancel(); } } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index b13db86c1..825146c29 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -9,7 +9,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; +import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; import com.jozufozu.flywheel.lib.modelpart.ModelPart; @@ -23,7 +23,7 @@ import net.minecraft.client.renderer.blockentity.BellRenderer; import net.minecraft.util.Mth; import net.minecraft.world.level.block.entity.BellBlockEntity; -public class BellInstance extends BlockEntityInstance implements DynamicInstance { +public class BellInstance extends AbstractBlockEntityInstance implements DynamicInstance { private static final SimpleLazyModel MODEL = new SimpleLazyModel(BellInstance::createBellModel, Materials.BELL); @@ -68,7 +68,7 @@ public class BellInstance extends BlockEntityInstance implement } @Override - public void remove() { + protected void _delete() { bell.delete(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index 1e6a59f15..c433763ab 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -11,7 +11,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; +import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; import com.jozufozu.flywheel.lib.modelpart.ModelPart; @@ -35,7 +35,7 @@ import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.entity.LidBlockEntity; import net.minecraft.world.level.block.state.properties.ChestType; -public class ChestInstance extends BlockEntityInstance implements DynamicInstance { +public class ChestInstance extends AbstractBlockEntityInstance implements DynamicInstance { private static final BiFunction LID = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createLidModel(type, mat), Materials.CHEST)); private static final BiFunction BASE = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createBaseModel(type, mat), Materials.CHEST)); @@ -117,7 +117,7 @@ public class ChestInstance extends Block } @Override - public void remove() { + protected void _delete() { body.delete(); lid.delete(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 2a2c60ad8..53f2561eb 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.api.model.Mesh; -import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; +import com.jozufozu.flywheel.lib.instance.AbstractEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.Models; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; @@ -26,7 +26,7 @@ import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -public class MinecartInstance extends EntityInstance implements DynamicInstance, TickableInstance { +public class MinecartInstance extends AbstractEntityInstance implements DynamicInstance, TickableInstance { private static final SimpleLazyModel MODEL = new SimpleLazyModel(MinecartInstance::getBodyModel, Materials.MINECART); @@ -150,7 +150,7 @@ public class MinecartInstance extends EntityInstance } @Override - public void remove() { + protected void _delete() { body.delete(); if (contents != null) contents.delete(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index 289caf4eb..a11f01c9b 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -8,7 +8,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; +import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; import com.jozufozu.flywheel.lib.modelpart.ModelPart; @@ -28,7 +28,7 @@ import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; -public class ShulkerBoxInstance extends BlockEntityInstance implements DynamicInstance { +public class ShulkerBoxInstance extends AbstractBlockEntityInstance implements DynamicInstance { private static final Function BASE = Util.memoize(it -> new SimpleLazyModel(() -> makeBaseModel(it), Materials.SHULKER)); private static final Function LID = Util.memoize(it -> new SimpleLazyModel(() -> makeLidModel(it), Materials.SHULKER)); @@ -95,7 +95,7 @@ public class ShulkerBoxInstance extends BlockEntityInstance createInstances(InstancerProvider instancerManager) { + public Collection createInstances(InstancerProvider instancerManager) { effects.clear(); boids.clear(); for (int i = 0; i < INSTANCE_COUNT; i++) { @@ -262,7 +262,7 @@ public class ExampleEffect implements Effect { } @Override - public void remove() { + protected void _delete() { instance.delete(); }