/* * This file is part of Applied Energistics 2. * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. * * Applied Energistics 2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Applied Energistics 2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Applied Energistics 2. If not, see . */ package appeng.me.cluster.implementations; import java.util.*; import appeng.api.networking.IGrid; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; import appeng.api.networking.crafting.*; import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.events.MENetworkCraftingCpuChange; import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.MachineSource; import appeng.api.storage.IMEInventory; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.WorldCoord; import appeng.me.cache.CraftingGridCache; import appeng.me.cluster.IAECluster; import appeng.tile.crafting.TileCraftingMonitorTile; import appeng.tile.crafting.TileCraftingTile; import net.minecraft.world.World; public final class CraftingCPUCluster extends AbstractCraftingCPU implements IAECluster { private final WorldCoord min; private final WorldCoord max; private final int[] usedOps = new int[3]; // INSTANCE sate private final LinkedList tiles = new LinkedList(); private final LinkedList storage = new LinkedList(); private final LinkedList status = new LinkedList(); private String myName = ""; private boolean isDestroyed = false; private MachineSource machineSrc = null; private long availableStorage = 0; private int accelerator = 0; public CraftingCPUCluster(final WorldCoord min, final WorldCoord max) { this.min = min; this.max = max; } @Override public boolean isDestroyed() { return this.isDestroyed; } public IMEInventory getInventory() { return this.inventory; } @Override public void updateStatus(final boolean updateGrid) { for (final TileCraftingTile r : this.tiles) { r.updateMeta(true); } } @Override public void destroy() { if (this.isDestroyed) { return; } this.isDestroyed = true; boolean posted = false; for (final TileCraftingTile r : this.tiles) { final IGridNode n = r.getActionableNode(); if (n != null && !posted) { final IGrid g = n.getGrid(); if (g != null) { g.postEvent(new MENetworkCraftingCpuChange(n)); posted = true; } } r.updateStatus(null); } } @Override public Iterator getTiles() { return (Iterator) this.tiles.iterator(); } void addTile(final TileCraftingTile te) { if (this.machineSrc == null || te.isCoreBlock()) { this.machineSrc = new MachineSource(te); } te.setCoreBlock(false); te.markDirty(); this.tiles.push(te); if (te.isStorage()) { this.availableStorage += te.getStorageBytes(); this.storage.add(te); } else if (te.isStatus()) { this.status.add((TileCraftingMonitorTile) te); } else if (te.isAccelerator()) { this.accelerator++; } } @Override protected void markDirty() { this.getCore().markDirty(); } @Override protected void updateCPU() { IAEItemStack send = this.finalOutput; if (this.finalOutput != null && this.finalOutput.getStackSize() <= 0) { send = null; } for (final TileCraftingMonitorTile t : this.status) { t.setJob(send); } } private TileCraftingTile getCore() { return (TileCraftingTile) this.machineSrc.via; } @Override protected IGrid getGrid() { for (final TileCraftingTile r : this.tiles) { final IGridNode gn = r.getActionableNode(); if (gn != null) { final IGrid g = gn.getGrid(); if (g != null) { return r.getActionableNode().getGrid(); } } } return null; } @Override public void updateCraftingLogic( final IGrid grid, final IEnergyGrid eg, final ICraftingGrid cc ) { if (!this.getCore().isActive()) { return; } if (this.myLastLink != null) { if (this.myLastLink.isCanceled()) { this.myLastLink = null; this.cancel(); } } if (this.isComplete) { if (this.inventory.getItemList().isEmpty()) { return; } this.storeItems(); return; } this.waiting = false; if (this.waiting || this.tasks.isEmpty()) // nothing to do here... { return; } this.remainingOperations = this.accelerator + 1 - (this.usedOps[0] + this.usedOps[1] + this.usedOps[2]); final int started = this.remainingOperations; if (this.remainingOperations > 0) { do { this.somethingChanged = false; this.executeCrafting(eg, (CraftingGridCache)cc); } while (this.somethingChanged && this.remainingOperations > 0); } this.usedOps[2] = this.usedOps[1]; this.usedOps[1] = this.usedOps[0]; this.usedOps[0] = started - this.remainingOperations; if (this.remainingOperations > 0 && !this.somethingChanged) { this.waiting = true; } } @Override public BaseActionSource getActionSource() { return this.machineSrc; } @Override public long getAvailableStorage() { return this.availableStorage; } @Override public int getCoProcessors() { return this.accelerator; } @Override public String getName() { return this.myName; } @Override public boolean isActive() { final TileCraftingTile core = this.getCore(); if (core == null) { return false; } final IGridNode node = core.getActionableNode(); if (node == null) { return false; } return node.isActive(); } void done() { final TileCraftingTile core = this.getCore(); core.setCoreBlock(true); if (core.getPreviousState() != null) { this.readFromNBT(core.getPreviousState()); core.setPreviousState(null); } this.updateCPU(); this.updateName(); } public void updateName() { this.myName = ""; for (final TileCraftingTile te : this.tiles) { if (te.hasCustomName()) { if (this.myName.length() > 0) { this.myName += ' ' + te.getCustomName(); } else { this.myName = te.getCustomName(); } } } } @Override protected World getWorld() { return this.getCore().getWorldObj(); } public void breakCluster() { final TileCraftingTile t = this.getCore(); if (t != null) { t.breakCluster(); } } }