mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-26 05:28:33 +01:00
network serialization
This commit is contained in:
parent
87de8e353d
commit
0a674ba1b5
2 changed files with 91 additions and 39 deletions
|
@ -1,14 +1,62 @@
|
||||||
package de.ellpeck.prettypipes.network;
|
package de.ellpeck.prettypipes.network;
|
||||||
|
|
||||||
|
import de.ellpeck.prettypipes.Utility;
|
||||||
|
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.Constants;
|
||||||
|
import net.minecraftforge.common.util.INBTSerializable;
|
||||||
import org.jgrapht.graph.DefaultWeightedEdge;
|
import org.jgrapht.graph.DefaultWeightedEdge;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class NetworkEdge extends DefaultWeightedEdge {
|
public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable<CompoundNBT> {
|
||||||
|
|
||||||
public TileEntity startPipe;
|
public final World world;
|
||||||
public List<TileEntity> pipes = new ArrayList<>();
|
public BlockPos startPipe;
|
||||||
public TileEntity endPipe;
|
public BlockPos endPipe;
|
||||||
|
public final List<BlockPos> pipes = new ArrayList<>();
|
||||||
|
private final Map<Integer, PipeTileEntity> tileCache = new HashMap<>();
|
||||||
|
|
||||||
|
public NetworkEdge(World world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipeTileEntity getPipe(int index) {
|
||||||
|
PipeTileEntity tile = this.tileCache.get(index);
|
||||||
|
if (tile == null || tile.isRemoved()) {
|
||||||
|
tile = Utility.getTileEntity(PipeTileEntity.class, this.world, this.pipes.get(index));
|
||||||
|
this.tileCache.put(index, tile);
|
||||||
|
}
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT serializeNBT() {
|
||||||
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
|
nbt.put("start", NBTUtil.writeBlockPos(this.startPipe));
|
||||||
|
nbt.put("end", NBTUtil.writeBlockPos(this.endPipe));
|
||||||
|
ListNBT list = new ListNBT();
|
||||||
|
for (BlockPos pos : this.pipes)
|
||||||
|
list.add(NBTUtil.writeBlockPos(pos));
|
||||||
|
nbt.put("pipes", list);
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserializeNBT(CompoundNBT nbt) {
|
||||||
|
this.startPipe = NBTUtil.readBlockPos(nbt.getCompound("start"));
|
||||||
|
this.endPipe = NBTUtil.readBlockPos(nbt.getCompound("end"));
|
||||||
|
this.pipes.clear();
|
||||||
|
ListNBT list = nbt.getList("pipes", Constants.NBT.TAG_COMPOUND);
|
||||||
|
for (int i = 0; i < list.size(); i++)
|
||||||
|
this.pipes.add(NBTUtil.readBlockPos(list.getCompound(i)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,28 +8,23 @@ import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||||
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.jgrapht.Graphs;
|
|
||||||
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
|
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
|
||||||
import org.jgrapht.graph.DefaultEdge;
|
|
||||||
import org.jgrapht.graph.DefaultWeightedEdge;
|
|
||||||
import org.jgrapht.graph.SimpleGraph;
|
|
||||||
import org.jgrapht.graph.SimpleWeightedGraph;
|
import org.jgrapht.graph.SimpleWeightedGraph;
|
||||||
import org.jheaps.tree.FibonacciHeap;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
|
|
||||||
|
@ -49,12 +44,30 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT serializeNBT() {
|
public CompoundNBT serializeNBT() {
|
||||||
return new CompoundNBT();
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
|
ListNBT nodes = new ListNBT();
|
||||||
|
for (BlockPos node : this.graph.vertexSet())
|
||||||
|
nodes.add(NBTUtil.writeBlockPos(node));
|
||||||
|
nbt.put("nodes", nodes);
|
||||||
|
ListNBT edges = new ListNBT();
|
||||||
|
for (NetworkEdge edge : this.graph.edgeSet())
|
||||||
|
edges.add(edge.serializeNBT());
|
||||||
|
nbt.put("edges", edges);
|
||||||
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeNBT(CompoundNBT nbt) {
|
public void deserializeNBT(CompoundNBT nbt) {
|
||||||
|
this.graph.removeAllVertices(new ArrayList<>(this.graph.vertexSet()));
|
||||||
|
ListNBT nodes = nbt.getList("nodes", Constants.NBT.TAG_COMPOUND);
|
||||||
|
for (int i = 0; i < nodes.size(); i++)
|
||||||
|
this.graph.addVertex(NBTUtil.readBlockPos(nodes.getCompound(i)));
|
||||||
|
ListNBT edges = nbt.getList("edges", Constants.NBT.TAG_COMPOUND);
|
||||||
|
for (int i = 0; i < edges.size(); i++) {
|
||||||
|
NetworkEdge edge = new NetworkEdge(this.world);
|
||||||
|
edge.deserializeNBT(edges.getCompound(i));
|
||||||
|
this.addEdge(edge);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNode(BlockPos pos, BlockState state) {
|
public void addNode(BlockPos pos, BlockState state) {
|
||||||
|
@ -74,21 +87,19 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
// if we only have one neighbor, then there can't be any new connections
|
// if we only have one neighbor, then there can't be any new connections
|
||||||
if (neighbors.size() <= 1 && !this.graph.containsVertex(pos))
|
if (neighbors.size() <= 1 && !this.graph.containsVertex(pos))
|
||||||
return;
|
return;
|
||||||
for (NetworkEdge edge : neighbors) {
|
for (NetworkEdge edge : neighbors)
|
||||||
BlockPos end = edge.endPipe.getPos();
|
this.refreshNode(edge.endPipe, this.world.getBlockState(edge.endPipe));
|
||||||
this.refreshNode(end, this.world.getBlockState(end));
|
|
||||||
}
|
|
||||||
System.out.println(this.graph.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshNode(BlockPos pos, BlockState state) {
|
private void refreshNode(BlockPos pos, BlockState state) {
|
||||||
Set<NetworkEdge> edges = this.graph.edgesOf(pos);
|
this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos)));
|
||||||
this.graph.removeAllEdges(new ArrayList<>(edges));
|
for (NetworkEdge edge : this.createAllEdges(pos, state, false))
|
||||||
|
this.addEdge(edge);
|
||||||
|
}
|
||||||
|
|
||||||
for (NetworkEdge edge : this.createAllEdges(pos, state, false)) {
|
private void addEdge(NetworkEdge edge) {
|
||||||
this.graph.addEdge(edge.startPipe.getPos(), edge.endPipe.getPos(), edge);
|
this.graph.addEdge(edge.startPipe, edge.endPipe, edge);
|
||||||
this.graph.setEdgeWeight(edge, edge.pipes.size());
|
this.graph.setEdgeWeight(edge, edge.pipes.size());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<NetworkEdge> createAllEdges(BlockPos pos, BlockState state, boolean allAround) {
|
private List<NetworkEdge> createAllEdges(BlockPos pos, BlockState state, boolean allAround) {
|
||||||
|
@ -108,17 +119,11 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
BlockState currState = this.world.getBlockState(currPos);
|
BlockState currState = this.world.getBlockState(currPos);
|
||||||
if (!(currState.getBlock() instanceof PipeBlock))
|
if (!(currState.getBlock() instanceof PipeBlock))
|
||||||
return null;
|
return null;
|
||||||
NetworkEdge edge = new NetworkEdge();
|
NetworkEdge edge = new NetworkEdge(this.world);
|
||||||
PipeTileEntity startPipe = Utility.getTileEntity(PipeTileEntity.class, this.world, pos);
|
edge.startPipe = pos;
|
||||||
if (startPipe != null) {
|
edge.pipes.add(pos);
|
||||||
edge.startPipe = startPipe;
|
edge.pipes.add(currPos);
|
||||||
edge.pipes.add(startPipe);
|
|
||||||
}
|
|
||||||
edge.pipes.add(Utility.getTileEntity(PipeTileEntity.class, this.world, currPos));
|
|
||||||
|
|
||||||
Set<BlockPos> seen = new HashSet<>();
|
|
||||||
seen.add(pos);
|
|
||||||
seen.add(currPos);
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// if we found a vertex, we can stop since that's the next node
|
// if we found a vertex, we can stop since that's the next node
|
||||||
// we do this here since the first offset pipe also needs to check this
|
// we do this here since the first offset pipe also needs to check this
|
||||||
|
@ -132,13 +137,12 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
|
||||||
if (!currState.get(PipeBlock.DIRECTIONS.get(nextDir)).isConnected())
|
if (!currState.get(PipeBlock.DIRECTIONS.get(nextDir)).isConnected())
|
||||||
continue;
|
continue;
|
||||||
BlockPos offset = currPos.offset(nextDir);
|
BlockPos offset = currPos.offset(nextDir);
|
||||||
if (seen.contains(offset))
|
|
||||||
continue;
|
|
||||||
seen.add(offset);
|
|
||||||
BlockState offState = this.world.getBlockState(offset);
|
BlockState offState = this.world.getBlockState(offset);
|
||||||
if (!(offState.getBlock() instanceof PipeBlock))
|
if (!(offState.getBlock() instanceof PipeBlock))
|
||||||
continue;
|
continue;
|
||||||
edge.pipes.add(Utility.getTileEntity(PipeTileEntity.class, this.world, offset));
|
if (edge.pipes.contains(offset))
|
||||||
|
continue;
|
||||||
|
edge.pipes.add(offset);
|
||||||
currPos = offset;
|
currPos = offset;
|
||||||
currState = offState;
|
currState = offState;
|
||||||
found = true;
|
found = true;
|
||||||
|
|
Loading…
Reference in a new issue