Applied-Energistics-2-tiler.../src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java

289 lines
7.9 KiB
Java

/*
* 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 <http://www.gnu.org/licenses/lgpl>.
*/
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<TileCraftingTile> tiles = new LinkedList<TileCraftingTile>();
private final LinkedList<TileCraftingTile> storage
= new LinkedList<TileCraftingTile>();
private final LinkedList<TileCraftingMonitorTile> status
= new LinkedList<TileCraftingMonitorTile>();
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<IAEItemStack> 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<IGridHost> 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();
}
}
}