farewell AbstractGrid
This commit is contained in:
parent
0ed841ab21
commit
162760c19c
@ -1,147 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.SectionPos;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
abstract public class AbstractGrid<T> {
|
|
||||||
protected final HashSet<T> cells = new HashSet<>();
|
|
||||||
public final Capability<T> capability;
|
|
||||||
|
|
||||||
protected AbstractGrid(Capability<T> capability) {
|
|
||||||
this.capability = capability;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
|
||||||
return cells.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected void onAdded(T cell);
|
|
||||||
abstract protected void onRemoved(T cell);
|
|
||||||
|
|
||||||
public boolean add(LazyOptional<T> cell) {
|
|
||||||
if (!cell.isPresent())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var resolved = cell.resolve();
|
|
||||||
|
|
||||||
if (resolved.isPresent()) {
|
|
||||||
final var value = resolved.get();
|
|
||||||
|
|
||||||
if (add(value)) {
|
|
||||||
cell.addListener((lazy) -> remove(value));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean add(T cell) {
|
|
||||||
if (cells.add(cell)) {
|
|
||||||
onAdded(cell);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean remove(T cell) {
|
|
||||||
if (cells.remove(cell)) {
|
|
||||||
onRemoved(cell);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void merge(AbstractGrid<T> other) {
|
|
||||||
if (other == this)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (size() < other.size()) {
|
|
||||||
var copy = List.copyOf(cells);
|
|
||||||
|
|
||||||
for (var cell : copy) {
|
|
||||||
remove(cell);
|
|
||||||
other.add(cell);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var copy = List.copyOf(other.cells);
|
|
||||||
|
|
||||||
for (var cell : copy) {
|
|
||||||
other.remove(cell);
|
|
||||||
add(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnNeighbourFunction<T> {
|
|
||||||
void apply(Level level, BlockPos pos, Direction dir, T other, BlockEntity ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> boolean createOrConnectGrid(
|
|
||||||
T self,
|
|
||||||
Capability<T> capability,
|
|
||||||
Level level,
|
|
||||||
BlockPos pos,
|
|
||||||
boolean force,
|
|
||||||
Supplier<AbstractGrid<T>> factory,
|
|
||||||
Function<T, AbstractGrid<T>> getter,
|
|
||||||
OnNeighbourFunction<T> neighbour
|
|
||||||
) {
|
|
||||||
if (getter.apply(self) != null && !force)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
boolean full_discovery = true;
|
|
||||||
|
|
||||||
for (Direction direction : Direction.values()) {
|
|
||||||
BlockPos offset = pos.offset(direction.getNormal());
|
|
||||||
|
|
||||||
// level.getBlockEntity can drink big cup of deadlocks
|
|
||||||
LevelChunk get_chunk = level.getChunkSource().getChunkNow(SectionPos.blockToSectionCoord(offset.getX()), SectionPos.blockToSectionCoord(offset.getZ()));
|
|
||||||
|
|
||||||
if (get_chunk == null) {
|
|
||||||
full_discovery = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockEntity get_entity = get_chunk.getBlockEntity(offset);
|
|
||||||
|
|
||||||
if (get_entity != null && get_entity.getCapability(capability, direction.getOpposite()).isPresent()) {
|
|
||||||
final var cell = get_entity.getCapability(capability, direction.getOpposite()).resolve().get();
|
|
||||||
final var grid = getter.apply(cell);
|
|
||||||
|
|
||||||
if (grid != null && grid != getter.apply(self)) {
|
|
||||||
if (getter.apply(self) == null) {
|
|
||||||
grid.add(self);
|
|
||||||
} else {
|
|
||||||
grid.merge(getter.apply(self));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
neighbour.apply(level, pos, direction, cell, get_entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getter.apply(self) == null) {
|
|
||||||
factory.get().add(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
return full_discovery;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user