package crazypants.enderio.conduit; import java.util.ArrayList; import java.util.Collection; import java.util.List; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; //I=base type, I is the base class of the implementations accepted by the network public abstract class AbstractConduitNetwork<T extends IConduit, I extends T> { protected final List<I> conduits = new ArrayList<I>(); protected final Class<I> implClass; protected final Class<T> baseConduitClass; protected AbstractConduitNetwork(Class<I> implClass, Class<T> baseConduitClass) { this.implClass = implClass; this.baseConduitClass = baseConduitClass; } public void init(IConduitBundle tile, Collection<I> connections, World world) { if(world.isRemote) { throw new UnsupportedOperationException(); } // Destroy all existing redstone networks around this block for (I con : connections) { AbstractConduitNetwork<?, ?> network = con.getNetwork(); if(network != null) { network.destroyNetwork(); } } setNetwork(world, tile); notifyNetworkOfUpdate(); } public final Class<T> getBaseConduitType() { return baseConduitClass; } protected void setNetwork(World world, IConduitBundle tile) { T conduit = tile.getConduit(getBaseConduitType()); if(conduit != null && implClass.isAssignableFrom(conduit.getClass()) && conduit.setNetwork(this)) { addConduit(implClass.cast(conduit)); TileEntity te = tile.getEntity(); Collection<T> connections = ConduitUtil.getConnectedConduits(world, te.xCoord, te.yCoord, te.zCoord, getBaseConduitType()); for (T con : connections) { if(con.getNetwork() == null) { setNetwork(world, con.getBundle()); } else if(con.getNetwork() != this) { con.getNetwork().destroyNetwork(); setNetwork(world, con.getBundle()); } } } } public void addConduit(I con) { if(!conduits.contains(con)) { if(conduits.isEmpty()) { ConduitNetworkTickHandler.instance.registerNetwork(this); } conduits.add(con); } } public void destroyNetwork() { for (I con : conduits) { con.setNetwork(null); } conduits.clear(); ConduitNetworkTickHandler.instance.unregisterNetwork(this); } public List<I> getConduits() { return conduits; } public void notifyNetworkOfUpdate() { for (I con : conduits) { TileEntity te = con.getBundle().getEntity(); te.getWorldObj().markBlockForUpdate(te.xCoord, te.yCoord, te.zCoord); } } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (IConduit con : conduits) { sb.append(con.getLocation()); sb.append(", "); } return "AbstractConduitNetwork [conduits=" + sb.toString() + "]"; } public void doNetworkTick() { } }