mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-14 14:25:00 +01:00
Recycling rope
- Bump flywheel version - Fix rope pulleys being invisible - Use an InstanceRecycler in AbstractPulleyVisual - Remove Select, Group, and ConditionalInstance
This commit is contained in:
parent
b6da803886
commit
eb2f1fecdc
8 changed files with 72 additions and 304 deletions
|
@ -23,7 +23,7 @@ use_parchment = true
|
|||
# dependency versions
|
||||
registrate_version = MC1.20-1.3.3
|
||||
flywheel_minecraft_version = 1.20.1
|
||||
flywheel_version = 1.0.0-beta-136
|
||||
flywheel_version = 1.0.0-beta-145
|
||||
jei_minecraft_version = 1.20.1
|
||||
jei_version = 15.10.0.39
|
||||
curios_minecraft_version = 1.20.1
|
||||
|
|
|
@ -5,17 +5,16 @@ import java.util.function.Consumer;
|
|||
import com.mojang.math.Axis;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.base.ShaftVisual;
|
||||
import com.simibubi.create.foundation.render.ConditionalInstance;
|
||||
import com.simibubi.create.foundation.render.GroupInstance;
|
||||
import com.simibubi.create.foundation.render.SelectInstance;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instance;
|
||||
import dev.engine_room.flywheel.api.instance.Instancer;
|
||||
import dev.engine_room.flywheel.api.visual.DynamicVisual;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
|
||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||
import dev.engine_room.flywheel.lib.math.MoreMath;
|
||||
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import dev.engine_room.flywheel.lib.visual.util.SmartRecycler;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
|
@ -29,9 +28,8 @@ import net.minecraft.world.level.LightLayer;
|
|||
|
||||
public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends ShaftVisual<T> implements SimpleDynamicVisual {
|
||||
private final OrientedInstance coil;
|
||||
private final SelectInstance<OrientedInstance> magnet;
|
||||
private final GroupInstance<OrientedInstance> rope;
|
||||
private final ConditionalInstance<OrientedInstance> halfRope;
|
||||
private final TransformedInstance magnet;
|
||||
private final SmartRecycler<Boolean, TransformedInstance> rope;
|
||||
|
||||
protected final Direction rotatingAbout;
|
||||
protected final Axis rotationAxis;
|
||||
|
@ -50,14 +48,12 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
.position(getVisualPosition());
|
||||
coil.setChanged();
|
||||
|
||||
magnet = new SelectInstance<>(this::getMagnetModelIndex);
|
||||
magnet.addModel(getMagnetModel())
|
||||
.addModel(getHalfMagnetModel());
|
||||
magnet = magnetInstancer().createInstance();
|
||||
|
||||
rope = new GroupInstance<>(getRopeModel());
|
||||
halfRope = new ConditionalInstance<>(getHalfRopeModel()).withCondition(this::shouldRenderHalfRope);
|
||||
rope = new SmartRecycler<>(b -> b ? getHalfRopeModel().createInstance() : getRopeModel().createInstance());
|
||||
|
||||
updateOffset(partialTick);
|
||||
updateLight(partialTick);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,67 +62,68 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
lightCache.updateSections();
|
||||
}
|
||||
|
||||
protected abstract Instancer<OrientedInstance> getRopeModel();
|
||||
protected abstract Instancer<TransformedInstance> getRopeModel();
|
||||
|
||||
protected abstract Instancer<OrientedInstance> getMagnetModel();
|
||||
protected abstract Instancer<TransformedInstance> getMagnetModel();
|
||||
|
||||
protected abstract Instancer<OrientedInstance> getHalfMagnetModel();
|
||||
protected abstract Instancer<TransformedInstance> getHalfMagnetModel();
|
||||
|
||||
protected abstract Instancer<OrientedInstance> getCoilModel();
|
||||
|
||||
protected abstract Instancer<OrientedInstance> getHalfRopeModel();
|
||||
protected abstract Instancer<TransformedInstance> getHalfRopeModel();
|
||||
|
||||
protected abstract float getOffset(float pt);
|
||||
|
||||
protected abstract boolean isRunning();
|
||||
|
||||
private Instancer<TransformedInstance> magnetInstancer() {
|
||||
return offset > .25f ? getMagnetModel() : getHalfMagnetModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(DynamicVisual.Context ctx) {
|
||||
updateOffset(ctx.partialTick());
|
||||
coil.rotation(rotationAxis.rotationDegrees(offset * 180))
|
||||
.setChanged();
|
||||
|
||||
int neededRopeCount = getNeededRopeCount();
|
||||
rope.resize(neededRopeCount);
|
||||
magnet.setVisible(isRunning() || offset == 0);
|
||||
|
||||
magnet.update()
|
||||
.get()
|
||||
.ifPresent(data -> {
|
||||
int i = Math.max(0, Mth.floor(offset));
|
||||
int light = lightCache.getPackedLight(i);
|
||||
data.position(getVisualPosition())
|
||||
.translatePosition(0, -offset, 0)
|
||||
.light(light)
|
||||
.setChanged();
|
||||
});
|
||||
magnetInstancer().stealInstance(magnet);
|
||||
|
||||
halfRope.update()
|
||||
.get()
|
||||
.ifPresent(rope1 -> {
|
||||
float f = offset % 1;
|
||||
float halfRopeNudge = f > .75f ? f - 1 : f;
|
||||
magnet.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.translate(0, -offset, 0)
|
||||
.light(lightCache.getPackedLight(Math.max(0, Mth.floor(offset))))
|
||||
.setChanged();
|
||||
|
||||
int light = lightCache.getPackedLight(0);
|
||||
rope1.position(getVisualPosition())
|
||||
.translatePosition(0, -halfRopeNudge, 0)
|
||||
.light(light)
|
||||
.setChanged();
|
||||
});
|
||||
rope.resetCount();
|
||||
|
||||
if (shouldRenderHalfRope()) {
|
||||
float f = offset % 1;
|
||||
float halfRopeNudge = f > .75f ? f - 1 : f;
|
||||
|
||||
rope.get(true).setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.translate(0, -halfRopeNudge, 0)
|
||||
.light(lightCache.getPackedLight(0))
|
||||
.setChanged();
|
||||
}
|
||||
|
||||
if (isRunning()) {
|
||||
int size = rope.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
int light = lightCache.getPackedLight(size - 1 - i);
|
||||
int neededRopeCount = getNeededRopeCount();
|
||||
|
||||
rope.get(i)
|
||||
.position(getVisualPosition())
|
||||
.translatePosition(0, -offset + i + 1, 0)
|
||||
.light(light)
|
||||
for (int i = 0; i < neededRopeCount; i++) {
|
||||
|
||||
rope.get(false)
|
||||
.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.translate(0, -offset + i + 1, 0)
|
||||
.light(lightCache.getPackedLight(neededRopeCount - 1 - i))
|
||||
.setChanged();
|
||||
}
|
||||
} else {
|
||||
rope.clear();
|
||||
}
|
||||
|
||||
rope.discardExtra();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,21 +148,11 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
return offset > .75f && (f < .25f || f > .75f);
|
||||
}
|
||||
|
||||
private int getMagnetModelIndex() {
|
||||
if (isRunning() || offset == 0) {
|
||||
return offset > .25f ? 0 : 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectCrumblingInstances(Consumer<Instance> consumer) {
|
||||
super.collectCrumblingInstances(consumer);
|
||||
consumer.accept(coil);
|
||||
magnet.forEach(consumer);
|
||||
rope.forEach(consumer);
|
||||
halfRope.forEach(consumer);
|
||||
consumer.accept(magnet);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,8 +160,7 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
super._delete();
|
||||
coil.delete();
|
||||
magnet.delete();
|
||||
rope.clear();
|
||||
halfRope.delete();
|
||||
rope.delete();
|
||||
}
|
||||
|
||||
private class LightCache {
|
||||
|
@ -186,6 +172,7 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
public void setSize(int size) {
|
||||
if (size != data.size()) {
|
||||
data.size(size);
|
||||
update();
|
||||
|
||||
int sectionCount = MoreMath.ceilingDiv(size + 15 - pos.getY() + pos.getY() / 4 * 4, SectionPos.SECTION_SIZE);
|
||||
if (sectionCount != this.sectionCount) {
|
||||
|
@ -215,7 +202,7 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
|
|||
for (int i = 0; i < data.size(); i++) {
|
||||
int blockLight = level.getBrightness(LightLayer.BLOCK, mutablePos);
|
||||
int skyLight = level.getBrightness(LightLayer.SKY, mutablePos);
|
||||
int light = ((skyLight << 4) & 0xF) | (blockLight & 0xF);
|
||||
int light = ((skyLight & 0xF) << 4) | (blockLight & 0xF);
|
||||
data.set(i, (byte) light);
|
||||
mutablePos.move(Direction.DOWN);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import dev.engine_room.flywheel.api.instance.Instancer;
|
|||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
|
||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||
import dev.engine_room.flywheel.lib.model.Models;
|
||||
|
||||
public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity> {
|
||||
|
@ -15,18 +16,18 @@ public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE));
|
||||
protected Instancer<TransformedInstance> getRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_MAGNET));
|
||||
protected Instancer<TransformedInstance> getMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_MAGNET));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getHalfMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET));
|
||||
protected Instancer<TransformedInstance> getHalfMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,8 +36,8 @@ public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getHalfRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF));
|
||||
protected Instancer<TransformedInstance> getHalfRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,6 +9,7 @@ import dev.engine_room.flywheel.api.instance.Instancer;
|
|||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
|
||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||
import dev.engine_room.flywheel.lib.model.Models;
|
||||
|
||||
public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
|
||||
|
@ -17,18 +18,18 @@ public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState()));
|
||||
protected Instancer<TransformedInstance> getRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState()));
|
||||
protected Instancer<TransformedInstance> getMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getHalfMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET));
|
||||
protected Instancer<TransformedInstance> getHalfMagnetModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,8 +38,8 @@ public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<OrientedInstance> getHalfRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF));
|
||||
protected Instancer<TransformedInstance> getHalfRopeModel() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -49,7 +49,7 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutByte(ptr + 33, instance.rotationAxisY);
|
||||
MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ);
|
||||
})
|
||||
.register();
|
||||
.build();
|
||||
|
||||
public static final InstanceType<BeltInstance> BELT = SimpleInstanceType.builder(BeltInstance::new)
|
||||
.cullShader(asResource("instance/cull/belt.glsl"))
|
||||
|
@ -87,7 +87,7 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutFloat(ptr + 68, instance.maxV);
|
||||
MemoryUtil.memPutFloat(ptr + 72, instance.scrollMult);
|
||||
})
|
||||
.register();
|
||||
.build();
|
||||
|
||||
// TODO: use this for belts too
|
||||
public static final InstanceType<ScrollInstance> SCROLLING = SimpleInstanceType.builder(ScrollInstance::new)
|
||||
|
@ -121,7 +121,7 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutFloat(ptr + 56, instance.scaleU);
|
||||
MemoryUtil.memPutFloat(ptr + 60, instance.scaleV);
|
||||
})
|
||||
.register();
|
||||
.build();
|
||||
|
||||
public static final InstanceType<ActorInstance> ACTOR = SimpleInstanceType.builder(ActorInstance::new)
|
||||
.cullShader(asResource("instance/cull/actor.glsl"))
|
||||
|
@ -151,7 +151,7 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutByte(ptr + 42, instance.rotationCenterZ);
|
||||
MemoryUtil.memPutFloat(ptr + 44, instance.speed);
|
||||
})
|
||||
.register();
|
||||
.build();
|
||||
|
||||
// TODO: remove
|
||||
public static final InstanceType<FlapInstance> FLAP = SimpleInstanceType.builder(FlapInstance::new)
|
||||
|
@ -183,7 +183,7 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutFloat(ptr + 48, instance.flapScale);
|
||||
MemoryUtil.memPutFloat(ptr + 52, instance.flapness);
|
||||
})
|
||||
.register();
|
||||
.build();
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
package com.simibubi.create.foundation.render;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instance;
|
||||
import dev.engine_room.flywheel.api.instance.Instancer;
|
||||
import dev.engine_room.flywheel.lib.instance.AbstractInstance;
|
||||
|
||||
public class ConditionalInstance<D extends AbstractInstance> {
|
||||
|
||||
final Instancer<D> model;
|
||||
ICondition condition;
|
||||
|
||||
Consumer<D> setupFunc;
|
||||
|
||||
@Nullable
|
||||
private D instance;
|
||||
|
||||
public ConditionalInstance(Instancer<D> model) {
|
||||
this.model = model;
|
||||
this.condition = () -> true;
|
||||
}
|
||||
|
||||
public ConditionalInstance<D> withSetupFunc(Consumer<D> setupFunc) {
|
||||
this.setupFunc = setupFunc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConditionalInstance<D> withCondition(ICondition condition) {
|
||||
this.condition = condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConditionalInstance<D> update() {
|
||||
boolean shouldShow = condition.shouldShow();
|
||||
if (shouldShow && instance == null) {
|
||||
instance = model.createInstance();
|
||||
if (setupFunc != null) setupFunc.accept(instance);
|
||||
} else if (!shouldShow && instance != null) {
|
||||
instance.delete();
|
||||
instance = null;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<D> get() {
|
||||
return Optional.ofNullable(instance);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (instance != null) instance.delete();
|
||||
}
|
||||
|
||||
public void forEach(Consumer<Instance> consumer) {
|
||||
if (instance != null) {
|
||||
consumer.accept(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ICondition {
|
||||
boolean shouldShow();
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package com.simibubi.create.foundation.render;
|
||||
|
||||
import java.util.AbstractCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instancer;
|
||||
import dev.engine_room.flywheel.lib.instance.AbstractInstance;
|
||||
|
||||
public class GroupInstance<D extends AbstractInstance> extends AbstractCollection<D> {
|
||||
|
||||
final Instancer<D> model;
|
||||
final List<D> backing;
|
||||
|
||||
public GroupInstance(Instancer<D> model) {
|
||||
this.model = model;
|
||||
|
||||
this.backing = new ArrayList<>();
|
||||
}
|
||||
|
||||
public GroupInstance(Instancer<D> model, int size) {
|
||||
this.model = model;
|
||||
|
||||
this.backing = new ArrayList<>(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
addInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param count
|
||||
* @return True if the number of elements changed.
|
||||
*/
|
||||
public boolean resize(int count) {
|
||||
int size = size();
|
||||
if (count == size) return false;
|
||||
|
||||
if (count <= 0) {
|
||||
clear();
|
||||
return size > 0;
|
||||
}
|
||||
|
||||
if (count > size) {
|
||||
for (int i = size; i < count; i++) {
|
||||
addInstance();
|
||||
}
|
||||
} else {
|
||||
List<D> unnecessary = backing.subList(count, size);
|
||||
unnecessary.forEach(AbstractInstance::delete);
|
||||
unnecessary.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public D addInstance() {
|
||||
D instance = model.createInstance();
|
||||
backing.add(instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public D get(int index) {
|
||||
return backing.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<D> iterator() {
|
||||
return backing.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return backing.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
backing.forEach(AbstractInstance::delete);
|
||||
backing.clear();
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package com.simibubi.create.foundation.render;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instance;
|
||||
import dev.engine_room.flywheel.api.instance.Instancer;
|
||||
|
||||
public class SelectInstance<D extends Instance> {
|
||||
|
||||
final List<Instancer<D>> models;
|
||||
|
||||
ModelSelector selector;
|
||||
|
||||
private int last = -1;
|
||||
@Nullable
|
||||
private D current;
|
||||
|
||||
public SelectInstance(ModelSelector selector) {
|
||||
this.models = new ArrayList<>();
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
public SelectInstance<D> addModel(Instancer<D> model) {
|
||||
models.add(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectInstance<D> update() {
|
||||
int i = selector.modelIndexToShow();
|
||||
|
||||
if (i < 0 || i >= models.size()) {
|
||||
if (current != null) {
|
||||
current.handle().setDeleted();
|
||||
current = null;
|
||||
}
|
||||
} else if (i != last) {
|
||||
if (current != null) current.handle().setDeleted();
|
||||
|
||||
current = models.get(i)
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
last = i;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<D> get() {
|
||||
return Optional.ofNullable(current);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (current != null) current.handle().setDeleted();
|
||||
}
|
||||
|
||||
public void forEach(Consumer<Instance> consumer) {
|
||||
if (current != null) {
|
||||
consumer.accept(current);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ModelSelector {
|
||||
int modelIndexToShow();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue