diff --git a/src/api/java/appeng/api/networking/IControllerCache.java b/src/api/java/appeng/api/networking/IControllerCache.java index 4049c6d2..5b30ead0 100644 --- a/src/api/java/appeng/api/networking/IControllerCache.java +++ b/src/api/java/appeng/api/networking/IControllerCache.java @@ -1,7 +1,8 @@ package appeng.api.networking; -import appeng.api.config.Actionable; -import appeng.api.storage.data.IAEItemStack; +import java.util.Set; + +import appeng.api.networking.crafting.ICraftingCPU; public interface IControllerCache extends IGridCache { @@ -15,6 +16,6 @@ public interface IControllerCache extends IGridCache { IGridHost getController(); - boolean requestCrafting(IAEItemStack stack, Actionable actionable); + Set getCPUs(); } diff --git a/src/main/java/appeng/block/legacy/BlockLegacyController.java b/src/main/java/appeng/block/legacy/BlockLegacyController.java index fe65c740..301f027d 100644 --- a/src/main/java/appeng/block/legacy/BlockLegacyController.java +++ b/src/main/java/appeng/block/legacy/BlockLegacyController.java @@ -8,6 +8,7 @@ import appeng.core.features.AEFeature; import appeng.core.sync.GuiBridge; import appeng.tile.legacy.TileLegacyController; import appeng.util.Platform; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; @@ -44,6 +45,13 @@ public class BlockLegacyController extends AEBaseTileBlock { return true; } + @Override + public void breakBlock(World w, int x, int y, int z, Block a, int b) { + TileLegacyController tile = this.getTileEntity(w, x, y, z); + tile.breakBlock(); + super.breakBlock(w, x, y, z, a, b); + } + @Override public IIcon getIcon(IBlockAccess w, int x, int y, int z, int s) { TileEntity te = w.getTileEntity(x, y, z); diff --git a/src/main/java/appeng/client/gui/implementations/GuiCraftConfirm.java b/src/main/java/appeng/client/gui/implementations/GuiCraftConfirm.java index 9624a18f..ab660737 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiCraftConfirm.java +++ b/src/main/java/appeng/client/gui/implementations/GuiCraftConfirm.java @@ -227,7 +227,7 @@ public class GuiCraftConfirm extends AEBaseGui { dsp = GuiText.Simulation.getLocal(); } else { dsp = this.ccc.getCpuAvailableBytes() > 0 - ? (GuiText.Bytes.getLocal() + ": " + this.ccc.getCpuAvailableBytes() + ? (GuiText.Bytes.getLocal() + ": " + (this.ccc.getCpuAvailableBytes() == Long.MAX_VALUE ? "Infinite" : this.ccc.getCpuAvailableBytes()) + " : " + GuiText.CoProcessors.getLocal() + ": " + this.ccc.getCpuCoProcessors()) : GuiText.Bytes.getLocal() + ": N/A : " + GuiText.CoProcessors.getLocal() diff --git a/src/main/java/appeng/core/sync/packets/PacketCraftRequest.java b/src/main/java/appeng/core/sync/packets/PacketCraftRequest.java index 67a27d6a..d36a94f6 100644 --- a/src/main/java/appeng/core/sync/packets/PacketCraftRequest.java +++ b/src/main/java/appeng/core/sync/packets/PacketCraftRequest.java @@ -20,8 +20,6 @@ package appeng.core.sync.packets; import java.util.concurrent.Future; -import appeng.api.config.Actionable; -import appeng.api.networking.IControllerCache; import appeng.api.networking.IGrid; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; @@ -89,10 +87,9 @@ public class PacketCraftRequest extends AppEngPacket { final ContainerOpenContext context = cca.getOpenContext(); IRequestGrid rg = g.getCache(IRequestGrid.class); - IControllerCache cgc = g.getCache(IControllerCache.class); IAEItemStack leftover = rg.requestItems(cca.getItemToCraft()); - if (leftover == null || cgc.requestCrafting(leftover, Actionable.MODULATE)) { + if (leftover == null) { cca.closeGui(); return; } diff --git a/src/main/java/appeng/me/cache/ControllerGridCache.java b/src/main/java/appeng/me/cache/ControllerGridCache.java index 16839b5a..c2141152 100644 --- a/src/main/java/appeng/me/cache/ControllerGridCache.java +++ b/src/main/java/appeng/me/cache/ControllerGridCache.java @@ -1,6 +1,7 @@ package appeng.me.cache; import java.util.HashSet; +import java.util.List; import java.util.Set; import appeng.api.config.Actionable; @@ -9,9 +10,11 @@ import appeng.api.networking.IGrid; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; import appeng.api.networking.IGridStorage; +import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.storage.data.IAEItemStack; import appeng.core.AEConfig; import appeng.core.features.AEFeature; +import appeng.me.cluster.implementations.InternalCraftingCPU; import appeng.tile.legacy.TileLegacyController; import appeng.tile.networking.TileController; @@ -90,10 +93,16 @@ public class ControllerGridCache implements IControllerCache { } @Override - public boolean requestCrafting(IAEItemStack stack, Actionable actionable) { - //ICraftingGrid craftingGrid = grid.getCache(ICraftingGrid.class); - //return craftingGrid.getCpus().isEmpty() && this.hasController(); - return false; // TODO: implement legacy crafting + public Set getCPUs() { + Set cpus = new HashSet<>(); + IGridHost h = getController(); + if (h instanceof TileLegacyController) { + TileLegacyController controller = (TileLegacyController) h; + for (InternalCraftingCPU cpu : controller.cpus) { + cpus.add(cpu); + } + } + return cpus; } } diff --git a/src/main/java/appeng/me/cache/CraftingGridCache.java b/src/main/java/appeng/me/cache/CraftingGridCache.java index 7752e2a0..09ec8a1a 100644 --- a/src/main/java/appeng/me/cache/CraftingGridCache.java +++ b/src/main/java/appeng/me/cache/CraftingGridCache.java @@ -27,6 +27,7 @@ import java.util.concurrent.ThreadFactory; import appeng.api.config.AccessRestriction; import appeng.api.config.Actionable; +import appeng.api.networking.IControllerCache; import appeng.api.networking.IGrid; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; @@ -52,6 +53,7 @@ import appeng.crafting.CraftingWatcher; import appeng.me.helpers.GenericInterestManager; import appeng.tile.crafting.TileCraftingStorageTile; import appeng.tile.crafting.TileCraftingTile; +import appeng.tile.legacy.TileLegacyController; import appeng.util.ItemSorters; import com.google.common.collect.*; import net.minecraft.world.World; @@ -181,7 +183,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper } } - if (machine instanceof TileCraftingTile) { + if (machine instanceof TileCraftingTile || machine instanceof TileLegacyController) { this.updateList = true; } @@ -259,6 +261,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper private void updateCPUClusters() { this.craftingCPUs.clear(); + IControllerCache cc = this.grid.getCache(IControllerCache.class); + craftingCPUs.addAll(cc.getCPUs()); for (final IGridNode cst : this.grid.getMachines(TileCraftingStorageTile.class)) { final TileCraftingStorageTile tile diff --git a/src/main/java/appeng/me/cluster/implementations/InternalCraftingCPU.java b/src/main/java/appeng/me/cluster/implementations/InternalCraftingCPU.java new file mode 100644 index 00000000..ad8ea4ca --- /dev/null +++ b/src/main/java/appeng/me/cluster/implementations/InternalCraftingCPU.java @@ -0,0 +1,137 @@ +package appeng.me.cluster.implementations; + +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.ICraftingGrid; +import appeng.api.networking.energy.IEnergyGrid; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.MachineSource; +import appeng.me.GridAccessException; +import appeng.me.cache.CraftingGridCache; +import appeng.tile.legacy.TileLegacyController; +import net.minecraft.world.World; + +public class InternalCraftingCPU extends AbstractCraftingCPU { + + private TileLegacyController controller; + private MachineSource actionSource; + private boolean isDestroyed = false; + private final int[] usedOps = new int[3]; + private int cpuNum; + + public InternalCraftingCPU(TileLegacyController controller, int cpuNum) { + this.controller = controller; + this.actionSource = new MachineSource(controller); + this.cpuNum = cpuNum; + } + + @Override + public BaseActionSource getActionSource() { + return this.actionSource; + } + + @Override + public long getAvailableStorage() { + return Long.MAX_VALUE; + } + + @Override + public int getCoProcessors() { + return 0; + } + + @Override + public String getName() { + return "Controller #" + this.cpuNum; + } + + public void updateCPUNum(int num) { + this.cpuNum = num; + } + + @Override + public void updateCraftingLogic(IGrid grid, IEnergyGrid eg, ICraftingGrid cc) { + if (!this.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 = 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 boolean isActive() { + return this.controller.getProxy().isActive(); + } + + @Override + public boolean isDestroyed() { + return this.isDestroyed; + } + + public void destroy() { + this.isDestroyed = true; + } + + @Override + protected IGrid getGrid() { + try { + return controller.getProxy().getGrid(); + } catch (GridAccessException e) { + return null; + } + } + + @Override + protected void markDirty() { + controller.markDirty(); + + } + + @Override + protected void updateCPU() { + + } + + @Override + protected World getWorld() { + return controller.getWorldObj(); + } + +} diff --git a/src/main/java/appeng/tile/legacy/TileLegacyController.java b/src/main/java/appeng/tile/legacy/TileLegacyController.java index 5ba1d3b6..01f81ecb 100644 --- a/src/main/java/appeng/tile/legacy/TileLegacyController.java +++ b/src/main/java/appeng/tile/legacy/TileLegacyController.java @@ -1,11 +1,16 @@ package appeng.tile.legacy; +import java.util.ArrayList; +import java.util.List; + import appeng.api.config.AccessRestriction; import appeng.api.config.Actionable; import appeng.api.events.LocatableEventAnnounce; import appeng.api.events.LocatableEventAnnounce.LocatableEvent; import appeng.api.features.ILocatable; +import appeng.api.networking.events.MENetworkCraftingCpuChange; import appeng.me.GridAccessException; +import appeng.me.cluster.implementations.InternalCraftingCPU; import appeng.tile.TileEvent; import appeng.tile.events.TileEventType; import appeng.tile.grid.AENetworkPowerTile; @@ -16,6 +21,7 @@ import io.netty.buffer.ByteBuf; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.ForgeDirection; @@ -23,10 +29,15 @@ public class TileLegacyController extends AENetworkPowerTile implements ILocatab public static final IInventory NULL_INVENTORY = new AppEngInternalInventory(null, 0); public static final int[] ACCESSIBLE_SLOTS_BY_SIDE = {}; public static int difference = 0; + public List cpus = new ArrayList<>(); + public int lastCPUNum = 0; + public int inactiveCPUs = 0; public int ticksSinceRefresh = 0; public long controllerKey; public int powerLevel; public int lastPowerLevel; + public static int MAX_CPUS = 100; + public static int MIN_INACTIVE = 2; public TileLegacyController() { this.setInternalMaxPower(10000); @@ -44,9 +55,10 @@ public class TileLegacyController extends AENetworkPowerTile implements ILocatab public void onTick() { if (!this.worldObj.isRemote) { ticksSinceRefresh++; - if (ticksSinceRefresh % 20 == 0) { + if (ticksSinceRefresh % 10 == 0) { ticksSinceRefresh = 0; updatePowerLevel(); + updateCPUs(); } } } @@ -123,6 +135,13 @@ public class TileLegacyController extends AENetworkPowerTile implements ILocatab @TileEvent(TileEventType.WORLD_NBT_WRITE) public void writeNBTTileLegacyController(final NBTTagCompound data) { data.setLong("controllerKey", this.controllerKey); + NBTTagList list = new NBTTagList(); + for (InternalCraftingCPU cpu : cpus) { + NBTTagCompound compound = new NBTTagCompound(); + cpu.writeToNBT(compound); + list.appendTag(compound); + } + data.setTag("cpus", list); } @TileEvent(TileEventType.WORLD_NBT_READ) @@ -130,6 +149,19 @@ public class TileLegacyController extends AENetworkPowerTile implements ILocatab if (data.hasKey("controllerKey")) { this.controllerKey = data.getLong("controllerKey"); } + if (data.hasKey("cpus")) { + this.lastCPUNum = 0; + this.cpus.clear(); + NBTTagList list = data.getTagList("cpus", 10); + int count = list.tagCount(); + for (int i = 0; i < count; i++) { + NBTTagCompound compound = list.getCompoundTagAt(i); + InternalCraftingCPU cpu = new InternalCraftingCPU(this, this.lastCPUNum); + this.lastCPUNum++; + cpu.readFromNBT(compound); + this.cpus.add(cpu); + } + } } @Override @@ -170,4 +202,69 @@ public class TileLegacyController extends AENetworkPowerTile implements ILocatab this.xCoord, this.yCoord, this.zCoord, this.xCoord, this.yCoord, this.zCoord ); } + + public void breakBlock() { + for (InternalCraftingCPU cpu : cpus) { + if (cpu.isBusy()) { + cpu.cancel(); + } + cpu.destroy(); + } + cpus.clear(); + try { + this.getProxy().getGrid().postEvent(new MENetworkCraftingCpuChange(this.getProxy().getNode())); + } catch (GridAccessException e) { + + } + } + + public void updateCPUs() { + this.inactiveCPUs = 0; + for (InternalCraftingCPU cpu : cpus) { + if (!cpu.isBusy()) this.inactiveCPUs++; + } + removeCPUs(); + int toCreate = Math.min(MIN_INACTIVE - this.inactiveCPUs, MAX_CPUS - this.cpus.size()); + if (toCreate > 0) { + createCPUs(toCreate); + } + } + + public void createCPUs(int amt) { + for (int i = 0; i < amt; i++) { + this.cpus.add(new InternalCraftingCPU(this, this.lastCPUNum)); + this.lastCPUNum++; + this.inactiveCPUs++; + } + try { + this.getProxy().getGrid().postEvent(new MENetworkCraftingCpuChange(this.getProxy().getNode())); + } catch (GridAccessException e) { + + } + } + + public void removeCPUs() { + boolean changed = false; + while (this.inactiveCPUs > MIN_INACTIVE) { + changed = changed || removeLastIfNotBusy(); + } + if (changed) { + try { + this.getProxy().getGrid().postEvent(new MENetworkCraftingCpuChange(this.getProxy().getNode())); + } catch (GridAccessException e) { + + } + } + } + + private boolean removeLastIfNotBusy() { + if (this.cpus.isEmpty()) return false; + InternalCraftingCPU cpu = this.cpus.get(cpus.size() - 1); + if (cpu.isBusy()) return false; + this.cpus.remove(cpu); + this.lastCPUNum--; + this.inactiveCPUs--; + cpu.destroy(); + return true; + } }