From fc7dd3e65a3ca4b2b05fa937577c190438b070cd Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Fri, 1 Aug 2014 13:04:31 -0400 Subject: [PATCH] Started on a new, more modular approach to controller-less multiblocks, allowing for the creation of the EIM --- .../RenderSalinationController.java | 2 +- .../common/CommonWorldTickHandler.java | 87 ++---- src/main/java/mekanism/common/Mekanism.java | 8 +- .../common/multiblock/MultiblockManager.java | 257 ++++++++++++++++++ .../common/tank/TankUpdateProtocol.java | 6 +- .../common/tile/TileEntityDynamicTank.java | 4 +- .../tile/TileEntityLogisticalSorter.java | 2 +- .../mekanism/common/util/MekanismUtils.java | 71 ----- 8 files changed, 293 insertions(+), 144 deletions(-) create mode 100644 src/main/java/mekanism/common/multiblock/MultiblockManager.java diff --git a/src/main/java/mekanism/client/render/tileentity/RenderSalinationController.java b/src/main/java/mekanism/client/render/tileentity/RenderSalinationController.java index f50f83946..e39153dca 100644 --- a/src/main/java/mekanism/client/render/tileentity/RenderSalinationController.java +++ b/src/main/java/mekanism/client/render/tileentity/RenderSalinationController.java @@ -43,7 +43,7 @@ public class RenderSalinationController extends TileEntitySpecialRenderer data.side = ForgeDirection.getOrientation(tileEntity.facing); bindTexture(MekanismRenderer.getBlocksTexture()); - + if(data.height >= 1 && tileEntity.waterTank.getCapacity() > 0) { Coord4D renderLoc = tileEntity.getRenderLocation(); diff --git a/src/main/java/mekanism/common/CommonWorldTickHandler.java b/src/main/java/mekanism/common/CommonWorldTickHandler.java index 470a1c9b3..a19bd8d83 100644 --- a/src/main/java/mekanism/common/CommonWorldTickHandler.java +++ b/src/main/java/mekanism/common/CommonWorldTickHandler.java @@ -4,15 +4,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; -import java.util.Map; import java.util.Queue; import java.util.Random; import mekanism.api.Coord4D; -import mekanism.common.tank.DynamicTankCache; -import mekanism.common.tile.TileEntityDynamicTank; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; +import mekanism.common.multiblock.MultiblockManager; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -24,6 +20,8 @@ public class CommonWorldTickHandler { private static final long maximumDeltaTimeNanoSecs = 16000000; // 16 milliseconds + public boolean loaded; + private HashMap> chunkRegenMap; public void addRegenChunk(int dimensionId, ChunkCoordIntPair chunkCoord) @@ -58,71 +56,36 @@ public class CommonWorldTickHandler @SubscribeEvent public void onTick(WorldTickEvent event) { - if(event.side == Side.SERVER && event.phase == Phase.END) + if(event.side == Side.SERVER) { - tickEnd(event.world); + if(event.phase == Phase.START) + { + tickStart(event.world); + } + else if(event.phase == Phase.END) + { + tickEnd(event.world); + } + } + } + + public void tickStart(World world) + { + if(!world.isRemote) + { + if(!loaded) + { + loaded = true; + MultiblockManager.load(world); + } } } public void tickEnd(World world) { - ArrayList idsToKill = new ArrayList(); - HashMap> tilesToKill = new HashMap>(); - if(!world.isRemote) { - for(Map.Entry entry : Mekanism.dynamicInventories.entrySet()) - { - int inventoryID = entry.getKey(); - - for(Coord4D obj : entry.getValue().locations) - { - if(obj.dimensionId == world.provider.dimensionId) - { - TileEntity tileEntity = obj.getTileEntity(world); - - if(!(tileEntity instanceof TileEntityDynamicTank) || ((TileEntityDynamicTank)tileEntity).inventoryID != inventoryID) - { - if(!tilesToKill.containsKey(inventoryID)) - { - tilesToKill.put(inventoryID, new HashSet()); - } - - tilesToKill.get(inventoryID).add(obj); - } - } - } - - if(entry.getValue().locations.isEmpty()) - { - idsToKill.add(inventoryID); - } - } - - for(Map.Entry> entry : tilesToKill.entrySet()) - { - for(Coord4D obj : entry.getValue()) - { - Mekanism.dynamicInventories.get(entry.getKey()).locations.remove(obj); - } - } - - for(int inventoryID : idsToKill) - { - for(Coord4D obj : Mekanism.dynamicInventories.get(inventoryID).locations) - { - TileEntityDynamicTank dynamicTank = (TileEntityDynamicTank)obj.getTileEntity(world); - - if(dynamicTank != null) - { - dynamicTank.cachedData = new DynamicTankCache(); - dynamicTank.inventory = new ItemStack[2]; - dynamicTank.inventoryID = -1; - } - } - - Mekanism.dynamicInventories.remove(inventoryID); - } + MultiblockManager.tick(world); if(chunkRegenMap == null) { diff --git a/src/main/java/mekanism/common/Mekanism.java b/src/main/java/mekanism/common/Mekanism.java index 5e226d75d..99875aeff 100644 --- a/src/main/java/mekanism/common/Mekanism.java +++ b/src/main/java/mekanism/common/Mekanism.java @@ -51,6 +51,7 @@ import mekanism.common.item.ItemBlockGasTank; import mekanism.common.item.ItemBlockMachine; import mekanism.common.item.ItemBlockOre; import mekanism.common.item.ItemBlockPlastic; +import mekanism.common.multiblock.MultiblockManager; import mekanism.common.multipart.MultipartMekanism; import mekanism.common.network.PacketDataRequest.DataRequestMessage; import mekanism.common.network.PacketTransmitterUpdate.PacketType; @@ -71,7 +72,6 @@ import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; import mekanism.common.voice.VoiceServerManager; import mekanism.common.world.GenHandler; - import net.minecraft.entity.EnumCreatureType; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -157,8 +157,8 @@ public class Mekanism /** Map of Teleporters */ public static Map> teleporters = new HashMap>(); - /** A map containing references to all dynamic tank inventory caches. */ - public static Map dynamicInventories = new HashMap(); + /** The Dynamic Tank multiblock manager */ + public static MultiblockManager tankManager = new MultiblockManager("dynamicTank"); /** Mekanism creative tab */ public static CreativeTabMekanism tabMekanism = new CreativeTabMekanism(); @@ -1066,13 +1066,13 @@ public class Mekanism //Clear all cache data teleporters.clear(); - dynamicInventories.clear(); ic2Registered.clear(); jetpackOn.clear(); gasmaskOn.clear(); activeVibrators.clear(); worldTickHandler.resetRegenChunks(); + MultiblockManager.reset(); TransporterManager.flowingStacks.clear(); } diff --git a/src/main/java/mekanism/common/multiblock/MultiblockManager.java b/src/main/java/mekanism/common/multiblock/MultiblockManager.java new file mode 100644 index 000000000..53fbeff47 --- /dev/null +++ b/src/main/java/mekanism/common/multiblock/MultiblockManager.java @@ -0,0 +1,257 @@ +package mekanism.common.multiblock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import mekanism.api.Coord4D; +import mekanism.common.tank.DynamicTankCache; +import mekanism.common.tile.TileEntityDynamicTank; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; +import net.minecraftforge.common.util.Constants.NBT; + +public class MultiblockManager +{ + private static Set managers = new HashSet(); + + public DataHandler dataHandler; + + public String name; + + /** A map containing references to all dynamic tank inventory caches. */ + public Map inventories = new HashMap(); + + public MultiblockManager(String s) + { + name = s; + managers.add(this); + } + + public void createOrLoad(World world) + { + if(dataHandler == null) + { + dataHandler = (DataHandler)world.perWorldStorage.loadData(DataHandler.class, name); + + if(dataHandler == null) + { + dataHandler = new DataHandler(); + world.perWorldStorage.setData(name, dataHandler); + } + } + } + + /** + * Grabs an inventory from the world's caches, and removes all the world's references to it. + * @param world - world the cache is stored in + * @param id - inventory ID to pull + * @return correct Dynamic Tank inventory cache + */ + public DynamicTankCache pullInventory(World world, int id) + { + DynamicTankCache toReturn = inventories.get(id); + + for(Coord4D obj : inventories.get(id).locations) + { + TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)obj.getTileEntity(world); + + if(tileEntity != null) + { + tileEntity.cachedData = new DynamicTankCache(); + tileEntity.inventory = new ItemStack[2]; + tileEntity.inventoryID = -1; + } + } + + inventories.remove(id); + dataHandler.markDirty(); + + return toReturn; + } + + /** + * Updates a dynamic tank cache with the defined inventory ID with the parameterized values. + * @param inventoryID - inventory ID of the dynamic tank + * @param cache - cache of the dynamic tank + * @param tileEntity - dynamic tank TileEntity + */ + public void updateCache(int inventoryID, DynamicTankCache cache, TileEntityDynamicTank tileEntity) + { + if(!inventories.containsKey(inventoryID)) + { + cache.locations.add(Coord4D.get(tileEntity)); + + inventories.put(inventoryID, cache); + + return; + } + + inventories.put(inventoryID, cache); + inventories.get(inventoryID).locations.add(Coord4D.get(tileEntity)); + dataHandler.markDirty(); + } + + /** + * Grabs a unique inventory ID for a dynamic tank. + * @return unique inventory ID + */ + public int getUniqueInventoryID() + { + int id = 0; + + while(true) + { + for(Integer i : inventories.keySet()) + { + if(id == i) + { + id++; + continue; + } + } + + return id; + } + } + + public static void tick(World world) + { + for(MultiblockManager manager : managers) + { + ArrayList idsToKill = new ArrayList(); + HashMap> tilesToKill = new HashMap>(); + + for(Map.Entry entry : manager.inventories.entrySet()) + { + int inventoryID = entry.getKey(); + + for(Coord4D obj : entry.getValue().locations) + { + if(obj.dimensionId == world.provider.dimensionId) + { + TileEntity tileEntity = obj.getTileEntity(world); + + if(!(tileEntity instanceof TileEntityDynamicTank) || ((TileEntityDynamicTank)tileEntity).inventoryID != inventoryID) + { + if(!tilesToKill.containsKey(inventoryID)) + { + tilesToKill.put(inventoryID, new HashSet()); + } + + tilesToKill.get(inventoryID).add(obj); + } + } + } + + if(entry.getValue().locations.isEmpty()) + { + idsToKill.add(inventoryID); + } + } + + for(Map.Entry> entry : tilesToKill.entrySet()) + { + for(Coord4D obj : entry.getValue()) + { + manager.inventories.get(entry.getKey()).locations.remove(obj); + manager.dataHandler.markDirty(); + } + } + + for(int inventoryID : idsToKill) + { + for(Coord4D obj : manager.inventories.get(inventoryID).locations) + { + TileEntityDynamicTank dynamicTank = (TileEntityDynamicTank)obj.getTileEntity(world); + + if(dynamicTank != null) + { + dynamicTank.cachedData = new DynamicTankCache(); + dynamicTank.inventory = new ItemStack[2]; + dynamicTank.inventoryID = -1; + } + } + + manager.inventories.remove(inventoryID); + manager.dataHandler.markDirty(); + } + } + } + + public static void load(World world) + { + for(MultiblockManager manager : managers) + { + manager.createOrLoad(world); + } + } + + public static void reset() + { + for(MultiblockManager manager : managers) + { + manager.inventories.clear(); + manager.dataHandler = null; + } + } + + public class DataHandler extends WorldSavedData + { + public DataHandler() + { + super(name); + } + + @Override + public void readFromNBT(NBTTagCompound nbtTags) + { + NBTTagList list = nbtTags.getTagList("invList", NBT.TAG_COMPOUND); + + for(int i = 0; i < list.tagCount(); i++) + { + NBTTagCompound compound = list.getCompoundTagAt(i); + DynamicTankCache cache = new DynamicTankCache(); + cache.load(compound); + + NBTTagList coordsList = compound.getTagList("coordsList", NBT.TAG_COMPOUND); + + for(int j = 0; j < coordsList.tagCount(); j++) + { + cache.locations.add(Coord4D.read(coordsList.getCompoundTagAt(j))); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound nbtTags) + { + NBTTagList list = new NBTTagList(); + + for(Map.Entry entry : inventories.entrySet()) + { + NBTTagCompound compound = new NBTTagCompound(); + compound.setInteger("id", entry.getKey()); + entry.getValue().save(compound); + + NBTTagList coordsList = new NBTTagList(); + + for(Coord4D coord : entry.getValue().locations) + { + coordsList.appendTag(coord.write(new NBTTagCompound())); + } + + compound.setTag("coordsList", coordsList); + list.appendTag(compound); + } + + nbtTags.setTag("invList", list); + } + } +} diff --git a/src/main/java/mekanism/common/tank/TankUpdateProtocol.java b/src/main/java/mekanism/common/tank/TankUpdateProtocol.java index 23deb90ff..0da9e4aaa 100644 --- a/src/main/java/mekanism/common/tank/TankUpdateProtocol.java +++ b/src/main/java/mekanism/common/tank/TankUpdateProtocol.java @@ -400,16 +400,16 @@ public class TankUpdateProtocol { for(int id : idsFound) { - if(Mekanism.dynamicInventories.get(id) != null) + if(Mekanism.tankManager.inventories.get(id) != null) { - cache = MekanismUtils.pullInventory(pointer.getWorldObj(), id); + cache = Mekanism.tankManager.pullInventory(pointer.getWorldObj(), id); idToUse = id; break; } } } else { - idToUse = MekanismUtils.getUniqueInventoryID(); + idToUse = Mekanism.tankManager.getUniqueInventoryID(); } cache.apply(structureFound); diff --git a/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java b/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java index 4fc85f90d..11849cb30 100644 --- a/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java +++ b/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java @@ -151,7 +151,7 @@ public class TileEntityDynamicTank extends TileEntityContainerBlock implements I if(inventoryID != -1 && structure == null) { - MekanismUtils.updateCache(inventoryID, cachedData, this); + Mekanism.tankManager.updateCache(inventoryID, cachedData, this); } if(structure == null && ticker == 5) @@ -190,7 +190,7 @@ public class TileEntityDynamicTank extends TileEntityContainerBlock implements I if(inventoryID != -1) { cachedData.sync(structure); - MekanismUtils.updateCache(inventoryID, cachedData, this); + Mekanism.tankManager.updateCache(inventoryID, cachedData, this); } manageInventory(); diff --git a/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java b/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java index 36353828d..a5cbe6c76 100644 --- a/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java +++ b/src/main/java/mekanism/common/tile/TileEntityLogisticalSorter.java @@ -486,7 +486,7 @@ public class TileEntityLogisticalSorter extends TileEntityElectricBlock implemen return new int[] {0}; } - return null; + return InventoryUtils.EMPTY; } @Override diff --git a/src/main/java/mekanism/common/util/MekanismUtils.java b/src/main/java/mekanism/common/util/MekanismUtils.java index 9272d55f3..dca95077d 100644 --- a/src/main/java/mekanism/common/util/MekanismUtils.java +++ b/src/main/java/mekanism/common/util/MekanismUtils.java @@ -887,77 +887,6 @@ public final class MekanismUtils player.openContainer.addCraftingToCrafters(player); } - /** - * Grabs an inventory from the world's caches, and removes all the world's references to it. - * @param world - world the cache is stored in - * @param id - inventory ID to pull - * @return correct Dynamic Tank inventory cache - */ - public static DynamicTankCache pullInventory(World world, int id) - { - DynamicTankCache toReturn = Mekanism.dynamicInventories.get(id); - - for(Coord4D obj : Mekanism.dynamicInventories.get(id).locations) - { - TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)obj.getTileEntity(world); - - if(tileEntity != null) - { - tileEntity.cachedData = new DynamicTankCache(); - tileEntity.inventory = new ItemStack[2]; - tileEntity.inventoryID = -1; - } - } - - Mekanism.dynamicInventories.remove(id); - - return toReturn; - } - - /** - * Updates a dynamic tank cache with the defined inventory ID with the parameterized values. - * @param inventoryID - inventory ID of the dynamic tank - * @param cache - cache of the dynamic tank - * @param tileEntity - dynamic tank TileEntity - */ - public static void updateCache(int inventoryID, DynamicTankCache cache, TileEntityDynamicTank tileEntity) - { - if(!Mekanism.dynamicInventories.containsKey(inventoryID)) - { - cache.locations.add(Coord4D.get(tileEntity)); - - Mekanism.dynamicInventories.put(inventoryID, cache); - - return; - } - - Mekanism.dynamicInventories.put(inventoryID, cache); - Mekanism.dynamicInventories.get(inventoryID).locations.add(Coord4D.get(tileEntity)); - } - - /** - * Grabs a unique inventory ID for a dynamic tank. - * @return unique inventory ID - */ - public static int getUniqueInventoryID() - { - int id = 0; - - while(true) - { - for(Integer i : Mekanism.dynamicInventories.keySet()) - { - if(id == i) - { - id++; - continue; - } - } - - return id; - } - } - /** * Retrieves a private value from a defined class and field. * @param obj - the Object to retrieve the value from, null if static