Document, annotate, and rename

- Add documentation for new InstancedRenderRegistry
 - Annotate TypeExtensions with Nullable
 - Add method for creating bulk instances
This commit is contained in:
Jozufozu 2022-01-04 14:14:30 -08:00
parent eb8dc6bc07
commit 379fe60ce6
8 changed files with 205 additions and 25 deletions

View file

@ -50,4 +50,14 @@ public interface Instancer<D extends InstanceData> {
* </p>
*/
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();
}
}
}

View file

@ -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 <T> The type of the block entity.
* @return {@code true} if the block entity type can be instanced.
*/
public static <T extends BlockEntity> 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 <T> The type of the entity.
* @return {@code true} if the entity type can be instanced.
*/
public static <T extends Entity> 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 <T> 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 <T extends BlockEntity> 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 <T> The type of the entity.
* @return An instance of the entity, or {@code null} if the entity cannot be instanced.
*/
@Nullable
public static <T extends Entity> 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 <T> The type of the block entity.
* @return {@code true} if the block entity is instanced and should not be rendered normally.
*/
public static <T extends BlockEntity> 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 <T> The type of the entity.
* @return {@code true} if the entity is instanced and should not be rendered normally.
*/
public static <T extends Entity> 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 <T> The type of the block entity.
* @return The configuration object.
*/
public static <T extends BlockEntity> BlockEntityConfig<T> configure(BlockEntityType<T> 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 <T> The type of the entity.
* @return The configuration object.
*/
public static <T extends Entity> EntityConfig<T> configure(EntityType<T> 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 <T> 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 <T extends BlockEntity> BlockEntityInstancingController<? super T> getBlockEntityController(BlockEntityType<T> type) {
public static <T extends BlockEntity> BlockEntityInstancingController<? super T> getController(BlockEntityType<T> type) {
return ((BlockEntityTypeExtension<T>) type).flywheel$getInstancingController();
}
@SuppressWarnings("unchecked")
public static <T extends BlockEntity> void setBlockEntityController(BlockEntityType<T> type, BlockEntityInstancingController<? super T> instancingController) {
((BlockEntityTypeExtension<T>) 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 <T> The type of the entity.
* @return The instancing controller for the given entity type, or {@code null} if none exists.
*/
@Nullable
public static <T extends Entity> EntityInstancingController<? super T> getEntityController(EntityType<T> type) {
public static <T extends Entity> EntityInstancingController<? super T> getController(EntityType<T> type) {
return ((EntityTypeExtension<T>) type).flywheel$getInstancingController();
}
@SuppressWarnings("unchecked")
public static <T extends Entity> void setEntityController(EntityType<T> 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 <T> The type of the block entity.
*/
public static <T extends BlockEntity> void setController(BlockEntityType<T> type, BlockEntityInstancingController<? super T> instancingController) {
((BlockEntityTypeExtension<T>) 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 <T> The type of the entity.
*/
public static <T extends Entity> void setController(EntityType<T> type, EntityInstancingController<? super T> instancingController) {
((EntityTypeExtension<T>) 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 <T> The type of the block entity.
* @return The {@link BlockEntityType} associated with the given block entity.
*/
public static <T extends BlockEntity> 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 <T> The type of the entity.
* @return The {@link EntityType} associated with the given entity.
*/
public static <T extends Entity> EntityType<? super T> getType(T entity) {
return (EntityType<? super T>) entity.getType();
}
/**
* An object to configure the instancing controller for a block entity.
* @param <T> The type of the block entity.
*/
public static class BlockEntityConfig<T extends BlockEntity> {
protected BlockEntityType<T> type;
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> 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<T> factory(BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> 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<T> skipRender(Predicate<T> skipRender) {
this.skipRender = skipRender;
return this;
}
/**
* Sets a predicate to always skip rendering for block entities of this type.
* @return {@code this}
*/
public BlockEntityConfig<T> 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<T> apply() {
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
if (skipRender == null) {
skipRender = be -> false;
}
SimpleBlockEntityInstancingController<T> controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender);
setBlockEntityController(type, controller);
setController(type, controller);
return controller;
}
}
/**
* An object to configure the instancing controller for an entity.
* @param <T> The type of the entity.
*/
public static class EntityConfig<T extends Entity> {
protected EntityType<T> type;
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> 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<T> factory(BiFunction<MaterialManager, T, EntityInstance<? super T>> 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<T> skipRender(Predicate<T> skipRender) {
this.skipRender = skipRender;
return this;
}
/**
* Sets a predicate to always skip rendering for entities of this type.
* @return {@code this}
*/
public EntityConfig<T> 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<T> apply() {
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
if (skipRender == null) {
skipRender = entity -> false;
}
SimpleEntityInstancingController<T> controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender);
setEntityController(type, controller);
setController(type, controller);
return controller;
}
}

View file

@ -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 <T> The type of block entity this controller is for.
*/
public interface BlockEntityInstancingController<T extends BlockEntity> {
/**
* 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);
}

View file

@ -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<T extends BlockEntity> {
@Nullable
BlockEntityInstancingController<? super T> flywheel$getInstancingController();
void flywheel$setInstancingController(BlockEntityInstancingController<? super T> instancingController);
void flywheel$setInstancingController(@Nullable BlockEntityInstancingController<? super T> instancingController);
}

View file

@ -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 <T> The entity type.
*/
public interface EntityInstancingController<T extends Entity> {
/**
* 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);
}

View file

@ -1,9 +1,12 @@
package com.jozufozu.flywheel.backend.instancing.entity;
import javax.annotation.Nullable;
import net.minecraft.world.entity.Entity;
public interface EntityTypeExtension<T extends Entity> {
@Nullable
EntityInstancingController<? super T> flywheel$getInstancingController();
void flywheel$setInstancingController(EntityInstancingController<? super T> instancingController);
void flywheel$setInstancingController(@Nullable EntityInstancingController<? super T> instancingController);
}

View file

@ -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<T extends BlockEntity> 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;
}
}

View file

@ -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<T extends Entity> implements EntityTypeExtension<T>
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;
}
}