diff --git a/src/main/java/com/jozufozu/flywheel/api/Instancer.java b/src/main/java/com/jozufozu/flywheel/api/Instancer.java
index 8ea0c3f70..5b6ac1cb4 100644
--- a/src/main/java/com/jozufozu/flywheel/api/Instancer.java
+++ b/src/main/java/com/jozufozu/flywheel/api/Instancer.java
@@ -50,4 +50,14 @@ public interface Instancer {
*
*/
void notifyRemoval();
+
+ /**
+ * Populate arr with new instances of this model.
+ * @param arr An array to fill.
+ */
+ default void createInstances(D[] arr) {
+ for (int i = 0; i < arr.length; i++) {
+ arr[i] = createInstance();
+ }
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java
index 87f43a90e..1946dabdb 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java
@@ -21,89 +21,177 @@ 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 {
+ /**
+ * Checks if the given block entity type can be instanced.
+ * @param type The block entity type to check.
+ * @param The type of the block entity.
+ * @return {@code true} if the block entity type can be instanced.
+ */
public static boolean canInstance(BlockEntityType extends T> type) {
- return getBlockEntityController(type) != null;
+ return getController(type) != null;
}
+ /**
+ * Checks if the given entity type can be instanced.
+ * @param type The entity type to check.
+ * @param The type of the entity.
+ * @return {@code true} if the entity type can be instanced.
+ */
public static boolean canInstance(EntityType extends T> type) {
- return getEntityController(type) != null;
+ return getController(type) != null;
}
+ /**
+ * Creates an instance for the given block entity, if possible.
+ * @param materialManager The material manager to use.
+ * @param blockEntity The block entity to create an instance of.
+ * @param The type of the block entity.
+ * @return An instance of the block entity, or {@code null} if the block entity cannot be instanced.
+ */
@Nullable
public static BlockEntityInstance super T> createInstance(MaterialManager materialManager, T blockEntity) {
- BlockEntityInstancingController super T> controller = getBlockEntityController(getType(blockEntity));
+ BlockEntityInstancingController super T> controller = getController(getType(blockEntity));
if (controller == null) {
return null;
}
return controller.createInstance(materialManager, blockEntity);
}
+ /**
+ * Creates an instance for the given entity, if possible.
+ * @param materialManager The material manager to use.
+ * @param entity The entity to create an instance of.
+ * @param The type of the entity.
+ * @return An instance of the entity, or {@code null} if the entity cannot be instanced.
+ */
@Nullable
public static EntityInstance super T> createInstance(MaterialManager materialManager, T entity) {
- EntityInstancingController super T> controller = getEntityController(getType(entity));
+ EntityInstancingController super T> controller = getController(getType(entity));
if (controller == null) {
return null;
}
return controller.createInstance(materialManager, entity);
}
+ /**
+ * Checks if the given block entity is instanced and should not be rendered normally.
+ * @param blockEntity The block entity to check.
+ * @param The type of the block entity.
+ * @return {@code true} if the block entity is instanced and should not be rendered normally.
+ */
public static boolean shouldSkipRender(T blockEntity) {
- BlockEntityInstancingController super T> controller = getBlockEntityController(getType(blockEntity));
+ BlockEntityInstancingController super T> controller = getController(getType(blockEntity));
if (controller == null) {
return false;
}
return controller.shouldSkipRender(blockEntity);
}
+ /**
+ * Checks if the given entity is instanced and should not be rendered normally.
+ * @param entity The entity to check.
+ * @param The type of the entity.
+ * @return {@code true} if the entity is instanced and should not be rendered normally.
+ */
public static boolean shouldSkipRender(T entity) {
- EntityInstancingController super T> controller = getEntityController(getType(entity));
+ EntityInstancingController super T> controller = getController(getType(entity));
if (controller == null) {
return false;
}
return controller.shouldSkipRender(entity);
}
+ /**
+ * Get an object to configure the instancing controller for the given block entity type.
+ * @param type The block entity type to configure.
+ * @param The type of the block entity.
+ * @return The configuration object.
+ */
public static BlockEntityConfig configure(BlockEntityType type) {
return new BlockEntityConfig<>(type);
}
+ /**
+ * Get an object to configure the instancing controller for the given entity type.
+ * @param type The entity type to configure.
+ * @param The type of the entity.
+ * @return The configuration object.
+ */
public static EntityConfig configure(EntityType type) {
return new EntityConfig<>(type);
}
- @SuppressWarnings("unchecked")
+ /**
+ * 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 super T> getBlockEntityController(BlockEntityType type) {
+ public static BlockEntityInstancingController super T> getController(BlockEntityType type) {
return ((BlockEntityTypeExtension) type).flywheel$getInstancingController();
}
- @SuppressWarnings("unchecked")
- public static void setBlockEntityController(BlockEntityType type, BlockEntityInstancingController super T> instancingController) {
- ((BlockEntityTypeExtension) type).flywheel$setInstancingController(instancingController);
- }
-
- @SuppressWarnings("unchecked")
+ /**
+ * 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 super T> getEntityController(EntityType type) {
+ public static EntityInstancingController super T> getController(EntityType type) {
return ((EntityTypeExtension) type).flywheel$getInstancingController();
}
- @SuppressWarnings("unchecked")
- public static void setEntityController(EntityType type, EntityInstancingController super T> instancingController) {
+ /**
+ * 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 super T> 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 super T> instancingController) {
((EntityTypeExtension) type).flywheel$setInstancingController(instancingController);
}
- @SuppressWarnings("unchecked")
+ /**
+ * 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.
+ */
public static BlockEntityType super T> getType(T blockEntity) {
return (BlockEntityType super T>) blockEntity.getType();
}
- @SuppressWarnings("unchecked")
+ /**
+ * Gets the type of the given entity.
+ * @param entity The entity to get the type of.
+ * @param The type of the entity.
+ * @return The {@link EntityType} associated with the given entity.
+ */
public static EntityType super T> getType(T entity) {
return (EntityType super T>) entity.getType();
}
+ /**
+ * An object to configure the instancing controller for a block entity.
+ * @param The type of the block entity.
+ */
public static class BlockEntityConfig {
protected BlockEntityType type;
protected BiFunction> instanceFactory;
@@ -113,32 +201,54 @@ public class InstancedRenderRegistry {
this.type = type;
}
+ /**
+ * Sets the instance factory for the block entity.
+ * @param instanceFactory The instance factory.
+ * @return {@code this}
+ */
public BlockEntityConfig factory(BiFunction> instanceFactory) {
this.instanceFactory = instanceFactory;
return this;
}
+ /**
+ * Sets a predicate to determine whether to skip rendering a block entity.
+ * @param skipRender The predicate.
+ * @return {@code this}
+ */
public BlockEntityConfig skipRender(Predicate skipRender) {
this.skipRender = skipRender;
return this;
}
+ /**
+ * Sets a predicate to always skip rendering for block entities of this type.
+ * @return {@code this}
+ */
public BlockEntityConfig alwaysSkipRender() {
this.skipRender = be -> true;
return this;
}
+ /**
+ * Constructs the block entity instancing controller, and sets it for the block entity type.
+ * @return The block entity instancing controller.
+ */
public SimpleBlockEntityInstancingController apply() {
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
if (skipRender == null) {
skipRender = be -> false;
}
SimpleBlockEntityInstancingController controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender);
- setBlockEntityController(type, controller);
+ setController(type, controller);
return controller;
}
}
+ /**
+ * An object to configure the instancing controller for an entity.
+ * @param The type of the entity.
+ */
public static class EntityConfig {
protected EntityType type;
protected BiFunction> instanceFactory;
@@ -148,28 +258,46 @@ public class InstancedRenderRegistry {
this.type = type;
}
+ /**
+ * Sets the instance factory for the entity.
+ * @param instanceFactory The instance factory.
+ * @return {@code this}
+ */
public EntityConfig factory(BiFunction> instanceFactory) {
this.instanceFactory = instanceFactory;
return this;
}
+ /**
+ * Sets a predicate to determine whether to skip rendering an entity.
+ * @param skipRender The predicate.
+ * @return {@code this}
+ */
public EntityConfig skipRender(Predicate skipRender) {
this.skipRender = skipRender;
return this;
}
+ /**
+ * Sets a predicate to always skip rendering for entities of this type.
+ * @return {@code this}
+ */
public EntityConfig alwaysSkipRender() {
this.skipRender = entity -> true;
return this;
}
+ /**
+ * Constructs the entity instancing controller, and sets it for the entity type.
+ * @return The entity instancing controller.
+ */
public SimpleEntityInstancingController apply() {
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
if (skipRender == null) {
skipRender = entity -> false;
}
SimpleEntityInstancingController controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender);
- setEntityController(type, controller);
+ setController(type, controller);
return controller;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java
index d2af7e459..23bf0b318 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java
@@ -4,8 +4,23 @@ import com.jozufozu.flywheel.api.MaterialManager;
import net.minecraft.world.level.block.entity.BlockEntity;
+/**
+ * An instancing controller that will be keyed to a block entity type.
+ * @param The type of block entity this controller is for.
+ */
public interface BlockEntityInstancingController {
+ /**
+ * Given a block entity and a material manager, constructs an instance for the block entity.
+ * @param materialManager The material manager to use.
+ * @param blockEntity The block entity to construct an instance for.
+ * @return The instance.
+ */
BlockEntityInstance super T> createInstance(MaterialManager materialManager, T blockEntity);
+ /**
+ * Checks if the given block entity should not be rendered normally.
+ * @param blockEntity The block entity to check.
+ * @return {@code true} if the block entity should not be rendered normally, {@code false} if it should.
+ */
boolean shouldSkipRender(T blockEntity);
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java
index e21f03334..3ac1bbb7e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java
@@ -1,9 +1,12 @@
package com.jozufozu.flywheel.backend.instancing.blockentity;
+import javax.annotation.Nullable;
+
import net.minecraft.world.level.block.entity.BlockEntity;
public interface BlockEntityTypeExtension {
+ @Nullable
BlockEntityInstancingController super T> flywheel$getInstancingController();
- void flywheel$setInstancingController(BlockEntityInstancingController super T> instancingController);
+ void flywheel$setInstancingController(@Nullable BlockEntityInstancingController super T> instancingController);
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java
index c835ca59e..740800f6b 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java
@@ -4,8 +4,23 @@ import com.jozufozu.flywheel.api.MaterialManager;
import net.minecraft.world.entity.Entity;
+/**
+ * An instancing controller that will be keyed to an entity type.
+ * @param The entity type.
+ */
public interface EntityInstancingController {
+ /**
+ * Given an entity and a material manager, constructs an instance for the entity.
+ * @param materialManager The material manager to use.
+ * @param entity The entity to construct an instance for.
+ * @return The instance.
+ */
EntityInstance super T> createInstance(MaterialManager materialManager, T entity);
+ /**
+ * Checks if the given entity should not render normally.
+ * @param entity The entity to check.
+ * @return {@code true} if the entity should not render normally, {@code false} if it should.
+ */
boolean shouldSkipRender(T entity);
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java
index cede41bbe..b01918acd 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java
@@ -1,9 +1,12 @@
package com.jozufozu.flywheel.backend.instancing.entity;
+import javax.annotation.Nullable;
+
import net.minecraft.world.entity.Entity;
public interface EntityTypeExtension {
+ @Nullable
EntityInstancingController super T> flywheel$getInstancingController();
- void flywheel$setInstancingController(EntityInstancingController super T> instancingController);
+ void flywheel$setInstancingController(@Nullable EntityInstancingController super T> instancingController);
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java
index c9f086957..ba5b86e18 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java
@@ -1,5 +1,7 @@
package com.jozufozu.flywheel.mixin;
+import javax.annotation.Nullable;
+
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@@ -15,12 +17,13 @@ public class BlockEntityTypeMixin implements BlockEntityT
private BlockEntityInstancingController super T> flywheel$instancingController;
@Override
+ @Nullable
public BlockEntityInstancingController super T> flywheel$getInstancingController() {
return flywheel$instancingController;
}
@Override
- public void flywheel$setInstancingController(BlockEntityInstancingController super T> instancingController) {
+ public void flywheel$setInstancingController(@Nullable BlockEntityInstancingController super T> instancingController) {
this.flywheel$instancingController = instancingController;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java
index 828232c4a..fdd14c9d2 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java
@@ -1,5 +1,7 @@
package com.jozufozu.flywheel.mixin;
+import javax.annotation.Nullable;
+
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@@ -15,12 +17,13 @@ public class EntityTypeMixin implements EntityTypeExtension
private EntityInstancingController super T> flywheel$instancingController;
@Override
+ @Nullable
public EntityInstancingController super T> flywheel$getInstancingController() {
return flywheel$instancingController;
}
@Override
- public void flywheel$setInstancingController(EntityInstancingController super T> instancingController) {
+ public void flywheel$setInstancingController(@Nullable EntityInstancingController super T> instancingController) {
this.flywheel$instancingController = instancingController;
}
}