Store away some classes

- Remove *VisualManager classes, promoting *Storage to the top level.
- AbstractVisualManager -> VisualManagerImpl.
- Parameterize VisualizationManagerImpl by the storage type.
This commit is contained in:
Jozufozu 2024-01-19 16:20:42 -08:00
parent 238fd68ef4
commit 500bd7ab0c
8 changed files with 162 additions and 193 deletions

View File

@ -21,9 +21,10 @@ import com.jozufozu.flywheel.api.visualization.VisualizationLevel;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.extension.LevelExtension;
import com.jozufozu.flywheel.impl.task.FlwTaskExecutor;
import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager;
import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager;
import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager;
import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityStorage;
import com.jozufozu.flywheel.impl.visualization.manager.EffectStorage;
import com.jozufozu.flywheel.impl.visualization.manager.EntityStorage;
import com.jozufozu.flywheel.impl.visualization.manager.VisualManagerImpl;
import com.jozufozu.flywheel.lib.task.Flag;
import com.jozufozu.flywheel.lib.task.IfElsePlan;
import com.jozufozu.flywheel.lib.task.MapContextPlan;
@ -49,9 +50,9 @@ public class VisualizationManagerImpl implements VisualizationManager {
private final Engine engine;
private final TaskExecutor taskExecutor;
private final BlockEntityVisualManager blockEntities;
private final EntityVisualManager entities;
private final EffectVisualManager effects;
private final VisualManagerImpl<BlockEntity, BlockEntityStorage> blockEntities;
private final VisualManagerImpl<Entity, EntityStorage> entities;
private final VisualManagerImpl<Effect, EffectStorage> effects;
private final Plan<TickContext> tickPlan;
private final Plan<RenderContext> framePlan;
@ -65,9 +66,9 @@ public class VisualizationManagerImpl implements VisualizationManager {
.createEngine(level);
taskExecutor = FlwTaskExecutor.get();
blockEntities = new BlockEntityVisualManager(engine);
entities = new EntityVisualManager(engine);
effects = new EffectVisualManager(engine);
blockEntities = new VisualManagerImpl<>(new BlockEntityStorage(engine));
entities = new VisualManagerImpl<>(new EntityStorage(engine));
effects = new VisualManagerImpl<>(new EffectStorage(engine));
tickPlan = blockEntities.createTickPlan()
.and(entities.createTickPlan())
@ -221,7 +222,8 @@ public class VisualizationManagerImpl implements VisualizationManager {
continue;
}
var visual = blockEntities.visualAtPos(entry.getLongKey());
var visual = blockEntities.getStorage()
.visualAtPos(entry.getLongKey());
if (visual == null) {
// The block doesn't have a visual, this is probably the common case.

View File

@ -0,0 +1,76 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.BlockEntityVisual;
import com.jozufozu.flywheel.api.visual.Visual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
public class BlockEntityStorage extends Storage<BlockEntity> {
private final Long2ObjectMap<BlockEntityVisual<?>> posLookup = new Long2ObjectOpenHashMap<>();
public BlockEntityStorage(Engine engine) {
super(engine);
}
public BlockEntityVisual<?> visualAtPos(long pos) {
return posLookup.get(pos);
}
@Override
public boolean willAccept(BlockEntity blockEntity) {
if (blockEntity.isRemoved()) {
return false;
}
if (!VisualizationHelper.canVisualize(blockEntity)) {
return false;
}
Level level = blockEntity.getLevel();
if (level == null) {
return false;
}
if (level.isEmptyBlock(blockEntity.getBlockPos())) {
return false;
}
BlockPos pos = blockEntity.getBlockPos();
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
return existingChunk != null;
}
@Override
@Nullable
protected Visual createRaw(BlockEntity obj) {
var visualizer = VisualizationHelper.getVisualizer(obj);
if (visualizer == null) {
return null;
}
var visual = visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj);
BlockPos blockPos = obj.getBlockPos();
posLookup.put(blockPos.asLong(), visual);
return visual;
}
@Override
public void remove(BlockEntity obj) {
super.remove(obj);
posLookup.remove(obj.getBlockPos()
.asLong());
}
}

View File

@ -1,88 +0,0 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.BlockEntityVisual;
import com.jozufozu.flywheel.api.visual.Visual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
public class BlockEntityVisualManager extends AbstractVisualManager<BlockEntity> {
private final BlockEntityStorage storage;
public BlockEntityVisualManager(Engine engine) {
storage = new BlockEntityStorage(engine);
}
@Override
protected Storage<BlockEntity> getStorage() {
return storage;
}
public BlockEntityVisual<?> visualAtPos(long pos) {
return storage.posLookup.get(pos);
}
private static class BlockEntityStorage extends Storage<BlockEntity> {
private final Long2ObjectMap<BlockEntityVisual<?>> posLookup = new Long2ObjectOpenHashMap<>();
public BlockEntityStorage(Engine engine) {
super(engine);
}
@Override
public boolean willAccept(BlockEntity blockEntity) {
if (blockEntity.isRemoved()) {
return false;
}
if (!VisualizationHelper.canVisualize(blockEntity)) {
return false;
}
Level level = blockEntity.getLevel();
if (level == null) {
return false;
}
if (level.isEmptyBlock(blockEntity.getBlockPos())) {
return false;
}
BlockPos pos = blockEntity.getBlockPos();
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
return existingChunk != null;
}
@Override
@Nullable
protected Visual createRaw(BlockEntity obj) {
var visualizer = VisualizationHelper.getVisualizer(obj);
if (visualizer == null) {
return null;
}
var visual = visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj);
BlockPos blockPos = obj.getBlockPos();
posLookup.put(blockPos.asLong(), visual);
return visual;
}
@Override
public void remove(BlockEntity obj) {
super.remove(obj);
posLookup.remove(obj.getBlockPos().asLong());
}
}
}

View File

@ -0,0 +1,23 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.Effect;
import com.jozufozu.flywheel.api.visual.EffectVisual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
public class EffectStorage extends Storage<Effect> {
public EffectStorage(Engine engine) {
super(engine);
}
@Override
protected EffectVisual<?> createRaw(Effect obj) {
return obj.visualize(new VisualizationContext(engine, engine.renderOrigin()));
}
@Override
public boolean willAccept(Effect obj) {
return true;
}
}

View File

@ -1,36 +0,0 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.Effect;
import com.jozufozu.flywheel.api.visual.EffectVisual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
public class EffectVisualManager extends AbstractVisualManager<Effect> {
private final EffectStorage storage;
public EffectVisualManager(Engine engine) {
storage = new EffectStorage(engine);
}
@Override
protected Storage<Effect> getStorage() {
return storage;
}
private static class EffectStorage extends Storage<Effect> {
public EffectStorage(Engine engine) {
super(engine);
}
@Override
protected EffectVisual<?> createRaw(Effect obj) {
return obj.visualize(new VisualizationContext(engine, engine.renderOrigin()));
}
@Override
public boolean willAccept(Effect obj) {
return true;
}
}
}

View File

@ -0,0 +1,43 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.Visual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
public class EntityStorage extends Storage<Entity> {
public EntityStorage(Engine engine) {
super(engine);
}
@Override
@Nullable
protected Visual createRaw(Entity obj) {
var visualizer = VisualizationHelper.getVisualizer(obj);
if (visualizer == null) {
return null;
}
return visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj);
}
@Override
public boolean willAccept(Entity entity) {
if (!entity.isAlive()) {
return false;
}
if (!VisualizationHelper.canVisualize(entity)) {
return false;
}
Level level = entity.level();
return level != null;
}
}

View File

@ -1,56 +0,0 @@
package com.jozufozu.flywheel.impl.visualization.manager;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.visual.Visual;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
public class EntityVisualManager extends AbstractVisualManager<Entity> {
private final EntityStorage storage;
public EntityVisualManager(Engine engine) {
storage = new EntityStorage(engine);
}
@Override
protected Storage<Entity> getStorage() {
return storage;
}
private static class EntityStorage extends Storage<Entity> {
public EntityStorage(Engine engine) {
super(engine);
}
@Override
@Nullable
protected Visual createRaw(Entity obj) {
var visualizer = VisualizationHelper.getVisualizer(obj);
if (visualizer == null) {
return null;
}
return visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj);
}
@Override
public boolean willAccept(Entity entity) {
if (!entity.isAlive()) {
return false;
}
if (!VisualizationHelper.canVisualize(entity)) {
return false;
}
Level level = entity.level();
return level != null;
}
}
}

View File

@ -18,18 +18,23 @@ import com.jozufozu.flywheel.impl.visualization.storage.Transaction;
import com.jozufozu.flywheel.lib.task.MapContextPlan;
import com.jozufozu.flywheel.lib.task.SimplePlan;
public abstract class AbstractVisualManager<T> implements VisualManager<T> {
public class VisualManagerImpl<T, S extends Storage<T>> implements VisualManager<T> {
private final Queue<Transaction<T>> queue = new ConcurrentLinkedQueue<>();
protected DistanceUpdateLimiterImpl tickLimiter;
protected DistanceUpdateLimiterImpl frameLimiter;
public AbstractVisualManager() {
protected final S storage;
public VisualManagerImpl(S storage) {
tickLimiter = createUpdateLimiter();
frameLimiter = createUpdateLimiter();
this.storage = storage;
}
protected abstract Storage<T> getStorage();
public S getStorage() {
return storage;
}
protected DistanceUpdateLimiterImpl createUpdateLimiter() {
if (FlwConfig.get()