Lots more moved
This commit is contained in:
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
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.networking.crafting.ICraftingCallback;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingJob;
|
||||
import appeng.api.networking.crafting.ICraftingLink;
|
||||
import appeng.api.networking.crafting.ICraftingMedium;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.crafting.ICraftingProvider;
|
||||
import appeng.api.networking.crafting.ICraftingProviderHelper;
|
||||
import appeng.api.networking.crafting.ICraftingRequester;
|
||||
import appeng.api.networking.crafting.ICraftingWatcher;
|
||||
import appeng.api.networking.crafting.ICraftingWatcherHost;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.events.MENetworkCraftingCpuChange;
|
||||
import appeng.api.networking.events.MENetworkCraftingPatternChange;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.events.MENetworkPostCacheConstruction;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.cells.ICellProvider;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.crafting.CraftingJob;
|
||||
import appeng.crafting.CraftingLink;
|
||||
import appeng.crafting.CraftingLinkNexus;
|
||||
import appeng.crafting.CraftingWatcher;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.me.helpers.BaseActionSource;
|
||||
import appeng.me.helpers.GenericInterestManager;
|
||||
import appeng.tile.crafting.CraftingStorageBlockEntity;
|
||||
import appeng.tile.crafting.CraftingBlockEntity;
|
||||
|
||||
public class CraftingGridCache
|
||||
implements ICraftingGrid, ICraftingProviderHelper, ICellProvider, IMEInventoryHandler<IAEItemStack> {
|
||||
|
||||
private static final ExecutorService CRAFTING_POOL;
|
||||
private static final Comparator<ICraftingPatternDetails> COMPARATOR = (firstDetail,
|
||||
nextDetail) -> nextDetail.getPriority() - firstDetail.getPriority();
|
||||
|
||||
static {
|
||||
final ThreadFactory factory = ar -> new Thread(ar, "AE Crafting Calculator");
|
||||
|
||||
CRAFTING_POOL = Executors.newCachedThreadPool(factory);
|
||||
}
|
||||
|
||||
private final Set<CraftingCPUCluster> craftingCPUClusters = new HashSet<>();
|
||||
private final Set<ICraftingProvider> craftingProviders = new HashSet<>();
|
||||
private final Map<IGridNode, ICraftingWatcher> craftingWatchers = new HashMap<>();
|
||||
private final IGrid grid;
|
||||
private final Map<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new HashMap<>();
|
||||
private final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new HashMap<>();
|
||||
private final Set<IAEItemStack> emitableItems = new HashSet<>();
|
||||
private final Map<String, CraftingLinkNexus> craftingLinks = new HashMap<>();
|
||||
private final Multimap<IAEStack, CraftingWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>(
|
||||
this.interests);
|
||||
private IStorageGrid storageGrid;
|
||||
private IEnergyGrid energyGrid;
|
||||
private boolean updateList = false;
|
||||
|
||||
public CraftingGridCache(final IGrid grid) {
|
||||
this.grid = grid;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void afterCacheConstruction(final MENetworkPostCacheConstruction cacheConstruction) {
|
||||
this.storageGrid = this.grid.getCache(IStorageGrid.class);
|
||||
this.energyGrid = this.grid.getCache(IEnergyGrid.class);
|
||||
|
||||
this.storageGrid.registerCellProvider(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
if (this.updateList) {
|
||||
this.updateList = false;
|
||||
this.updateCPUClusters();
|
||||
}
|
||||
|
||||
final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator();
|
||||
while (craftingLinkIterator.hasNext()) {
|
||||
if (craftingLinkIterator.next().isDead(this.grid, this)) {
|
||||
craftingLinkIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
for (final CraftingCPUCluster cpu : this.craftingCPUClusters) {
|
||||
cpu.updateCraftingLogic(this.grid, this.energyGrid, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof ICraftingWatcherHost) {
|
||||
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get(machine);
|
||||
if (craftingWatcher != null) {
|
||||
craftingWatcher.reset();
|
||||
this.craftingWatchers.remove(machine);
|
||||
}
|
||||
}
|
||||
|
||||
if (machine instanceof ICraftingRequester) {
|
||||
for (final CraftingLinkNexus link : this.craftingLinks.values()) {
|
||||
if (link.isMachine(machine)) {
|
||||
link.removeNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (machine instanceof CraftingBlockEntity) {
|
||||
this.updateList = true;
|
||||
}
|
||||
|
||||
if (machine instanceof ICraftingProvider) {
|
||||
this.craftingProviders.remove(machine);
|
||||
this.updatePatterns();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof ICraftingWatcherHost) {
|
||||
final ICraftingWatcherHost watcherHost = (ICraftingWatcherHost) machine;
|
||||
final CraftingWatcher watcher = new CraftingWatcher(this, watcherHost);
|
||||
this.craftingWatchers.put(gridNode, watcher);
|
||||
watcherHost.updateWatcher(watcher);
|
||||
}
|
||||
|
||||
if (machine instanceof ICraftingRequester) {
|
||||
for (final ICraftingLink link : ((ICraftingRequester) machine).getRequestedJobs()) {
|
||||
if (link instanceof CraftingLink) {
|
||||
this.addLink((CraftingLink) link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (machine instanceof CraftingBlockEntity) {
|
||||
this.updateList = true;
|
||||
}
|
||||
|
||||
if (machine instanceof ICraftingProvider) {
|
||||
this.craftingProviders.add((ICraftingProvider) machine);
|
||||
this.updatePatterns();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit(final IGridStorage destinationStorage) { // nothing!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin(final IGridStorage sourceStorage) {
|
||||
// nothing!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage destinationStorage) {
|
||||
// nothing!
|
||||
}
|
||||
|
||||
private void updatePatterns() {
|
||||
final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = this.craftableItems;
|
||||
|
||||
// erase list.
|
||||
this.craftingMethods.clear();
|
||||
this.craftableItems.clear();
|
||||
this.emitableItems.clear();
|
||||
|
||||
// update the stuff that was in the list...
|
||||
this.storageGrid.postAlterationOfStoredItems(
|
||||
AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), oldItems.keySet(),
|
||||
new BaseActionSource());
|
||||
|
||||
// re-create list..
|
||||
for (final ICraftingProvider provider : this.craftingProviders) {
|
||||
provider.provideCrafting(this);
|
||||
}
|
||||
|
||||
final Map<IAEItemStack, Set<ICraftingPatternDetails>> tmpCraft = new HashMap<>();
|
||||
|
||||
// new craftables!
|
||||
for (final ICraftingPatternDetails details : this.craftingMethods.keySet()) {
|
||||
for (IAEItemStack out : details.getOutputs()) {
|
||||
out = out.copy();
|
||||
out.reset();
|
||||
out.setCraftable(true);
|
||||
|
||||
Set<ICraftingPatternDetails> methods = tmpCraft.get(out);
|
||||
|
||||
if (methods == null) {
|
||||
tmpCraft.put(out, methods = new TreeSet<>(COMPARATOR));
|
||||
}
|
||||
|
||||
methods.add(details);
|
||||
}
|
||||
}
|
||||
|
||||
// make them immutable
|
||||
for (final Entry<IAEItemStack, Set<ICraftingPatternDetails>> e : tmpCraft.entrySet()) {
|
||||
this.craftableItems.put(e.getKey(), ImmutableList.copyOf(e.getValue()));
|
||||
}
|
||||
|
||||
this.storageGrid.postAlterationOfStoredItems(
|
||||
AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class), this.craftableItems.keySet(),
|
||||
new BaseActionSource());
|
||||
}
|
||||
|
||||
private void updateCPUClusters() {
|
||||
this.craftingCPUClusters.clear();
|
||||
|
||||
for (final IGridNode cst : this.grid.getMachines(CraftingStorageBlockEntity.class)) {
|
||||
final CraftingStorageBlockEntity tile = (CraftingStorageBlockEntity) cst.getMachine();
|
||||
final CraftingCPUCluster cluster = (CraftingCPUCluster) tile.getCluster();
|
||||
if (cluster != null) {
|
||||
this.craftingCPUClusters.add(cluster);
|
||||
|
||||
if (cluster.getLastCraftingLink() != null) {
|
||||
this.addLink((CraftingLink) cluster.getLastCraftingLink());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addLink(final CraftingLink link) {
|
||||
if (link.isStandalone()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CraftingLinkNexus nexus = this.craftingLinks.get(link.getCraftingID());
|
||||
if (nexus == null) {
|
||||
this.craftingLinks.put(link.getCraftingID(), nexus = new CraftingLinkNexus(link.getCraftingID()));
|
||||
}
|
||||
|
||||
link.setNexus(nexus);
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void updateCPUClusters(final MENetworkCraftingCpuChange c) {
|
||||
this.updateList = true;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void updateCPUClusters(final MENetworkCraftingPatternChange c) {
|
||||
this.updatePatterns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCraftingOption(final ICraftingMedium medium, final ICraftingPatternDetails api) {
|
||||
List<ICraftingMedium> details = this.craftingMethods.get(api);
|
||||
if (details == null) {
|
||||
details = new ArrayList<>();
|
||||
details.add(medium);
|
||||
this.craftingMethods.put(api, details);
|
||||
} else {
|
||||
details.add(medium);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmitable(final IAEItemStack someItem) {
|
||||
this.emitableItems.add(someItem.copy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IMEInventoryHandler> getCellArray(final IStorageChannel<?> channel) {
|
||||
final List<IMEInventoryHandler> list = new ArrayList<>(1);
|
||||
|
||||
if (channel == AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)) {
|
||||
list.add(this);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized(final IAEItemStack input) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept(final IAEItemStack input) {
|
||||
for (final CraftingCPUCluster cpu : this.craftingCPUClusters) {
|
||||
if (cpu.canAccept(input)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return i == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems(IAEItemStack input, final Actionable type, final IActionSource src) {
|
||||
for (final CraftingCPUCluster cpu : this.craftingCPUClusters) {
|
||||
input = cpu.injectItems(input, type, src);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems(final IAEItemStack request, final Actionable mode, final IActionSource src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems(final IItemList<IAEItemStack> out) {
|
||||
// add craftable items!
|
||||
for (final IAEItemStack stack : this.craftableItems.keySet()) {
|
||||
out.addCrafting(stack);
|
||||
}
|
||||
|
||||
for (final IAEItemStack st : this.emitableItems) {
|
||||
out.addCrafting(st);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableCollection<ICraftingPatternDetails> getCraftingFor(final IAEItemStack whatToCraft,
|
||||
final ICraftingPatternDetails details, final int slotIndex, final World world) {
|
||||
final ImmutableList<ICraftingPatternDetails> res = this.craftableItems.get(whatToCraft);
|
||||
|
||||
if (res == null) {
|
||||
if (details != null && details.isCraftable()) {
|
||||
for (final IAEItemStack ais : this.craftableItems.keySet()) {
|
||||
if (ais.getItem() == whatToCraft.getItem()
|
||||
&& (!ais.getItem().isDamageable() || ais.getItemDamage() == whatToCraft.getItemDamage())) {
|
||||
// TODO: check if OK
|
||||
// TODO: this is slightly hacky, but fine as long as we only deal with
|
||||
// itemstacks
|
||||
if (details.isValidItemForSlot(slotIndex, ais.asItemStackRepresentation(), world)) {
|
||||
return this.craftableItems.get(ais);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<ICraftingJob> beginCraftingJob(final World world, final IGrid grid, final IActionSource actionSrc,
|
||||
final IAEItemStack slotItem, final ICraftingCallback cb) {
|
||||
if (world == null || grid == null || actionSrc == null || slotItem == null) {
|
||||
throw new IllegalArgumentException("Invalid Crafting Job Request");
|
||||
}
|
||||
|
||||
final CraftingJob job = new CraftingJob(world, grid, actionSrc, slotItem, cb);
|
||||
|
||||
return CRAFTING_POOL.submit(job, (ICraftingJob) job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingLink submitJob(final ICraftingJob job, final ICraftingRequester requestingMachine,
|
||||
final ICraftingCPU target, final boolean prioritizePower, final IActionSource src) {
|
||||
if (job.isSimulation()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CraftingCPUCluster cpuCluster = null;
|
||||
|
||||
if (target instanceof CraftingCPUCluster) {
|
||||
cpuCluster = (CraftingCPUCluster) target;
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
final List<CraftingCPUCluster> validCpusClusters = new ArrayList<>();
|
||||
for (final CraftingCPUCluster cpu : this.craftingCPUClusters) {
|
||||
if (cpu.isActive() && !cpu.isBusy() && cpu.getAvailableStorage() >= job.getByteTotal()) {
|
||||
validCpusClusters.add(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(validCpusClusters, (firstCluster, nextCluster) -> {
|
||||
if (prioritizePower) {
|
||||
final int comparison1 = Long.compare(nextCluster.getCoProcessors(), firstCluster.getCoProcessors());
|
||||
if (comparison1 != 0) {
|
||||
return comparison1;
|
||||
}
|
||||
return Long.compare(nextCluster.getAvailableStorage(), firstCluster.getAvailableStorage());
|
||||
}
|
||||
|
||||
final int comparison2 = Long.compare(firstCluster.getCoProcessors(), nextCluster.getCoProcessors());
|
||||
if (comparison2 != 0) {
|
||||
return comparison2;
|
||||
}
|
||||
return Long.compare(firstCluster.getAvailableStorage(), nextCluster.getAvailableStorage());
|
||||
});
|
||||
|
||||
if (!validCpusClusters.isEmpty()) {
|
||||
cpuCluster = validCpusClusters.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpuCluster != null) {
|
||||
return cpuCluster.submitJob(this.grid, job, src, requestingMachine);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableSet<ICraftingCPU> getCpus() {
|
||||
return ImmutableSet.copyOf(new ActiveCpuIterator(this.craftingCPUClusters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEmitFor(final IAEItemStack someItem) {
|
||||
return this.emitableItems.contains(someItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequesting(final IAEItemStack what) {
|
||||
return this.requesting(what) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long requesting(IAEItemStack what) {
|
||||
long requested = 0;
|
||||
|
||||
for (final CraftingCPUCluster cluster : this.craftingCPUClusters) {
|
||||
final IAEItemStack stack = cluster.making(what);
|
||||
requested += stack != null ? stack.getStackSize() : 0;
|
||||
}
|
||||
|
||||
return requested;
|
||||
}
|
||||
|
||||
public List<ICraftingMedium> getMediums(final ICraftingPatternDetails key) {
|
||||
List<ICraftingMedium> mediums = this.craftingMethods.get(key);
|
||||
|
||||
if (mediums == null) {
|
||||
mediums = ImmutableList.of();
|
||||
}
|
||||
|
||||
return mediums;
|
||||
}
|
||||
|
||||
public boolean hasCpu(final ICraftingCPU cpu) {
|
||||
return this.craftingCPUClusters.contains(cpu);
|
||||
}
|
||||
|
||||
public GenericInterestManager<CraftingWatcher> getInterestManager() {
|
||||
return this.interestManager;
|
||||
}
|
||||
|
||||
private static class ActiveCpuIterator implements Iterator<ICraftingCPU> {
|
||||
|
||||
private final Iterator<CraftingCPUCluster> iterator;
|
||||
private CraftingCPUCluster cpuCluster;
|
||||
|
||||
public ActiveCpuIterator(final Collection<CraftingCPUCluster> o) {
|
||||
this.iterator = o.iterator();
|
||||
this.cpuCluster = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
this.findNext();
|
||||
|
||||
return this.cpuCluster != null;
|
||||
}
|
||||
|
||||
private void findNext() {
|
||||
while (this.iterator.hasNext() && this.cpuCluster == null) {
|
||||
this.cpuCluster = this.iterator.next();
|
||||
if (!this.cpuCluster.isActive() || this.cpuCluster.isDestroyed()) {
|
||||
this.cpuCluster = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingCPU next() {
|
||||
final ICraftingCPU o = this.cpuCluster;
|
||||
this.cpuCluster = null;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no..
|
||||
}
|
||||
}
|
||||
}
|
||||
+183
-10
@@ -1,41 +1,214 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridCache;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.api.networking.events.MENetworkBootingStatusChange;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
||||
import appeng.api.networking.ticking.ITickManager;
|
||||
import appeng.core.AELog;
|
||||
import appeng.me.cache.helpers.TunnelCollection;
|
||||
import appeng.parts.p2p.MEP2PTunnelPart;
|
||||
import appeng.parts.p2p.P2PTunnelPart;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
// FIXME FABRIC DUMMY
|
||||
public class P2PCache implements IGridCache {
|
||||
private static final TunnelCollection<P2PTunnelPart> NULL_COLLECTION = new TunnelCollection<P2PTunnelPart>(null,
|
||||
null);
|
||||
|
||||
private final IGrid myGrid;
|
||||
private final HashMap<Short, P2PTunnelPart> inputs = new HashMap<>();
|
||||
private final Multimap<Short, P2PTunnelPart> outputs = LinkedHashMultimap.create();
|
||||
private final Random frequencyGenerator;
|
||||
|
||||
public P2PCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
this.frequencyGenerator = new Random(g.hashCode());
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete(final MENetworkBootingStatusChange bootStatus) {
|
||||
final ITickManager tm = this.myGrid.getCache(ITickManager.class);
|
||||
for (final P2PTunnelPart me : this.inputs.values()) {
|
||||
if (me instanceof MEP2PTunnelPart) {
|
||||
tm.wakeDevice(me.getGridNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete(final MENetworkPowerStatusChange power) {
|
||||
final ITickManager tm = this.myGrid.getCache(ITickManager.class);
|
||||
for (final P2PTunnelPart me : this.inputs.values()) {
|
||||
if (me instanceof MEP2PTunnelPart) {
|
||||
tm.wakeDevice(me.getGridNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(@Nonnull IGridNode gridNode, @Nonnull IGridHost machine) {
|
||||
public void removeNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof P2PTunnelPart) {
|
||||
if (machine instanceof MEP2PTunnelPart) {
|
||||
if (!node.hasFlag(GridFlags.REQUIRE_CHANNEL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final P2PTunnelPart t = (P2PTunnelPart) machine;
|
||||
// AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
|
||||
if (t.isOutput()) {
|
||||
this.outputs.remove(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.remove(t.getFrequency());
|
||||
}
|
||||
|
||||
this.updateTunnel(t.getFrequency(), !t.isOutput(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof P2PTunnelPart) {
|
||||
if (machine instanceof MEP2PTunnelPart) {
|
||||
if (!node.hasFlag(GridFlags.REQUIRE_CHANNEL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final P2PTunnelPart t = (P2PTunnelPart) machine;
|
||||
// AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
|
||||
if (t.isOutput()) {
|
||||
this.outputs.put(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.put(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
this.updateTunnel(t.getFrequency(), !t.isOutput(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(@Nonnull IGridNode gridNode, @Nonnull IGridHost machine) {
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit(@Nonnull IGridStorage destinationStorage) {
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin(@Nonnull IGridStorage sourceStorage) {
|
||||
private void updateTunnel(final short freq, final boolean updateOutputs, final boolean configChange) {
|
||||
for (final P2PTunnelPart p : this.outputs.get(freq)) {
|
||||
if (configChange) {
|
||||
p.onTunnelConfigChange();
|
||||
}
|
||||
p.onTunnelNetworkChange();
|
||||
}
|
||||
|
||||
final P2PTunnelPart in = this.inputs.get(freq);
|
||||
if (in != null) {
|
||||
if (configChange) {
|
||||
in.onTunnelConfigChange();
|
||||
}
|
||||
in.onTunnelNetworkChange();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage(@Nonnull IGridStorage destinationStorage) {
|
||||
public void updateFreq(final P2PTunnelPart t, final short newFrequency) {
|
||||
if (this.outputs.containsValue(t)) {
|
||||
this.outputs.remove(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
if (this.inputs.containsValue(t)) {
|
||||
this.inputs.remove(t.getFrequency());
|
||||
}
|
||||
|
||||
t.setFrequency(newFrequency);
|
||||
|
||||
if (t.isOutput()) {
|
||||
this.outputs.put(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.put(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
this.updateTunnel(t.getFrequency(), t.isOutput(), true);
|
||||
this.updateTunnel(t.getFrequency(), !t.isOutput(), true);
|
||||
}
|
||||
|
||||
public short newFrequency() {
|
||||
short newFrequency;
|
||||
int cycles = 0;
|
||||
|
||||
do {
|
||||
newFrequency = (short) this.frequencyGenerator.nextInt(1 << 16);
|
||||
cycles++;
|
||||
} while (newFrequency == 0 || this.inputs.containsKey(newFrequency));
|
||||
|
||||
if (cycles > 25) {
|
||||
AELog.debug("Generating a new P2P frequency '%1$d' took %2$d cycles", newFrequency, cycles);
|
||||
}
|
||||
|
||||
return newFrequency;
|
||||
}
|
||||
|
||||
public TunnelCollection<P2PTunnelPart> getOutputs(final short freq, final Class<? extends P2PTunnelPart> c) {
|
||||
final P2PTunnelPart in = this.inputs.get(freq);
|
||||
|
||||
if (in == null) {
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
|
||||
final TunnelCollection<P2PTunnelPart> out = this.inputs.get(freq).getCollection(this.outputs.get(freq), c);
|
||||
|
||||
if (out == null) {
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public P2PTunnelPart getInput(final short freq) {
|
||||
return this.inputs.get(freq);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,6 +25,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.tile.networking.ControllerBlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
@@ -56,7 +57,6 @@ import appeng.me.pathfinding.ControllerChannelUpdater;
|
||||
import appeng.me.pathfinding.ControllerValidator;
|
||||
import appeng.me.pathfinding.IPathItem;
|
||||
import appeng.me.pathfinding.PathSegment;
|
||||
import appeng.tile.networking.ControllerBlockEntity;
|
||||
|
||||
public class PathGridCache implements IPathingGrid {
|
||||
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.api.networking.events.MENetworkBootingStatusChange;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.spatial.ISpatialCache;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.me.cluster.implementations.SpatialPylonCluster;
|
||||
import appeng.tile.spatial.SpatialIOPortBlockEntity;
|
||||
import appeng.tile.spatial.SpatialPylonBlockEntity;
|
||||
|
||||
public class SpatialPylonCache implements ISpatialCache {
|
||||
|
||||
private final IGrid myGrid;
|
||||
private long powerRequired = 0;
|
||||
private double efficiency = 0.0;
|
||||
private DimensionalCoord captureMin;
|
||||
private DimensionalCoord captureMax;
|
||||
private boolean isValid = false;
|
||||
private List<SpatialIOPortBlockEntity> ioPorts = new ArrayList<>();
|
||||
private HashMap<SpatialPylonCluster, SpatialPylonCluster> clusters = new HashMap<>();
|
||||
|
||||
public SpatialPylonCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootingRender(final MENetworkBootingStatusChange c) {
|
||||
this.reset(this.myGrid);
|
||||
}
|
||||
|
||||
private void reset(final IGrid grid) {
|
||||
|
||||
this.clusters = new HashMap<>();
|
||||
this.ioPorts = new ArrayList<>();
|
||||
|
||||
for (final IGridNode gm : grid.getMachines(SpatialIOPortBlockEntity.class)) {
|
||||
this.ioPorts.add((SpatialIOPortBlockEntity) gm.getMachine());
|
||||
}
|
||||
|
||||
final IReadOnlyCollection<IGridNode> set = grid.getMachines(SpatialPylonBlockEntity.class);
|
||||
for (final IGridNode gm : set) {
|
||||
if (gm.meetsChannelRequirements()) {
|
||||
final SpatialPylonCluster c = ((SpatialPylonBlockEntity) gm.getMachine()).getCluster();
|
||||
if (c != null) {
|
||||
this.clusters.put(c, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.captureMax = null;
|
||||
this.captureMin = null;
|
||||
this.isValid = true;
|
||||
|
||||
int pylonBlocks = 0;
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
if (this.captureMax == null) {
|
||||
this.captureMax = cl.getMax().copy();
|
||||
}
|
||||
if (this.captureMin == null) {
|
||||
this.captureMin = cl.getMin().copy();
|
||||
}
|
||||
|
||||
pylonBlocks += cl.tileCount();
|
||||
|
||||
this.captureMin.x = Math.min(this.captureMin.x, cl.getMin().x);
|
||||
this.captureMin.y = Math.min(this.captureMin.y, cl.getMin().y);
|
||||
this.captureMin.z = Math.min(this.captureMin.z, cl.getMin().z);
|
||||
|
||||
this.captureMax.x = Math.max(this.captureMax.x, cl.getMax().x);
|
||||
this.captureMax.y = Math.max(this.captureMax.y, cl.getMax().y);
|
||||
this.captureMax.z = Math.max(this.captureMax.z, cl.getMax().z);
|
||||
}
|
||||
|
||||
double maxPower = 0;
|
||||
double minPower = 0;
|
||||
if (this.hasRegion()) {
|
||||
this.isValid = this.captureMax.x - this.captureMin.x > 1 && this.captureMax.y - this.captureMin.y > 1
|
||||
&& this.captureMax.z - this.captureMin.z > 1;
|
||||
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
switch (cl.getCurrentAxis()) {
|
||||
case X:
|
||||
|
||||
this.isValid = this.isValid
|
||||
&& ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl.getMax().y)
|
||||
|| (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z))
|
||||
&& ((this.captureMax.y == cl.getMax().y || this.captureMin.y == cl.getMin().y)
|
||||
|| (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
|
||||
|
||||
break;
|
||||
case Y:
|
||||
|
||||
this.isValid = this.isValid
|
||||
&& ((this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x)
|
||||
|| (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z))
|
||||
&& ((this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x)
|
||||
|| (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
|
||||
|
||||
break;
|
||||
case Z:
|
||||
|
||||
this.isValid = this.isValid
|
||||
&& ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl.getMax().y)
|
||||
|| (this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x))
|
||||
&& ((this.captureMax.y == cl.getMax().y || this.captureMin.y == cl.getMin().y)
|
||||
|| (this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x));
|
||||
|
||||
break;
|
||||
case UNFORMED:
|
||||
this.isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final int reqX = this.captureMax.x - this.captureMin.x;
|
||||
final int reqY = this.captureMax.y - this.captureMin.y;
|
||||
final int reqZ = this.captureMax.z - this.captureMin.z;
|
||||
final int requirePylonBlocks = Math.max(6, ((reqX * reqZ + reqX * reqY + reqY * reqZ) * 3) / 8);
|
||||
|
||||
this.efficiency = (double) pylonBlocks / (double) requirePylonBlocks;
|
||||
|
||||
if (this.efficiency > 1.0) {
|
||||
this.efficiency = 1.0;
|
||||
}
|
||||
if (this.efficiency < 0.0) {
|
||||
this.efficiency = 0.0;
|
||||
}
|
||||
|
||||
minPower = (double) reqX * (double) reqY * reqZ * AEConfig.instance().getSpatialPowerMultiplier();
|
||||
maxPower = Math.pow(minPower, AEConfig.instance().getSpatialPowerExponent());
|
||||
}
|
||||
|
||||
final double affective_efficiency = Math.pow(this.efficiency, 0.25);
|
||||
this.powerRequired = (long) (affective_efficiency * minPower + (1.0 - affective_efficiency) * maxPower);
|
||||
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
final boolean myWasValid = cl.isValid();
|
||||
cl.setValid(this.isValid);
|
||||
if (myWasValid != this.isValid) {
|
||||
cl.updateStatus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRegion() {
|
||||
return this.captureMin != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidRegion() {
|
||||
return this.hasRegion() && this.isValid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionalCoord getMin() {
|
||||
return this.captureMin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionalCoord getMax() {
|
||||
return this.captureMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long requiredPower() {
|
||||
return this.powerRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float currentEfficiency() {
|
||||
return (float) this.efficiency * 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(final IGridNode node, final IGridHost machine) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(final IGridNode node, final IGridHost machine) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.cache.helpers;
|
||||
|
||||
import appeng.api.networking.IGridConnection;
|
||||
|
||||
public class ConnectionWrapper {
|
||||
|
||||
private IGridConnection connection;
|
||||
|
||||
public ConnectionWrapper(final IGridConnection gc) {
|
||||
this.setConnection(gc);
|
||||
}
|
||||
|
||||
public IGridConnection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public void setConnection(final IGridConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.cache.helpers;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.parts.p2p.MEP2PTunnelPart;
|
||||
import appeng.util.IWorldCallable;
|
||||
|
||||
public class Connections implements IWorldCallable<Void> {
|
||||
|
||||
private final HashMap<IGridNode, TunnelConnection> connections = new HashMap<>();
|
||||
private final MEP2PTunnelPart me;
|
||||
private boolean create = false;
|
||||
private boolean destroy = false;
|
||||
|
||||
public Connections(final MEP2PTunnelPart o) {
|
||||
this.me = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void call(final World world) throws Exception {
|
||||
this.me.updateConnections(this);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void markDestroy() {
|
||||
this.setCreate(false);
|
||||
this.setDestroy(true);
|
||||
}
|
||||
|
||||
public void markCreate() {
|
||||
this.setCreate(true);
|
||||
this.setDestroy(false);
|
||||
}
|
||||
|
||||
public HashMap<IGridNode, TunnelConnection> getConnections() {
|
||||
return this.connections;
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
return this.create;
|
||||
}
|
||||
|
||||
private void setCreate(final boolean create) {
|
||||
this.create = create;
|
||||
}
|
||||
|
||||
public boolean isDestroy() {
|
||||
return this.destroy;
|
||||
}
|
||||
|
||||
private void setDestroy(final boolean destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.cache.helpers;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import appeng.parts.p2p.P2PTunnelPart;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
public class TunnelCollection<T extends P2PTunnelPart> implements Iterable<T> {
|
||||
|
||||
private final Class clz;
|
||||
private Collection<T> tunnelSources;
|
||||
|
||||
public TunnelCollection(final Collection<T> src, final Class c) {
|
||||
this.tunnelSources = src;
|
||||
this.clz = c;
|
||||
}
|
||||
|
||||
public void setSource(final Collection<T> c) {
|
||||
this.tunnelSources = c;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return !this.iterator().hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
if (this.tunnelSources == null) {
|
||||
return new NullIterator<>();
|
||||
}
|
||||
return new TunnelIterator<>(this.tunnelSources, this.clz);
|
||||
}
|
||||
|
||||
public boolean matches(final Class<? extends P2PTunnelPart> c) {
|
||||
return this.clz == c;
|
||||
}
|
||||
|
||||
public Class<? extends P2PTunnelPart> getClz() {
|
||||
return this.clz;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.tunnelSources == null ? 0 : this.tunnelSources.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.cache.helpers;
|
||||
|
||||
import appeng.api.networking.IGridConnection;
|
||||
import appeng.parts.p2p.MEP2PTunnelPart;
|
||||
|
||||
public class TunnelConnection {
|
||||
|
||||
private final MEP2PTunnelPart tunnel;
|
||||
private final IGridConnection c;
|
||||
|
||||
public TunnelConnection(final MEP2PTunnelPart t, final IGridConnection con) {
|
||||
this.tunnel = t;
|
||||
this.c = con;
|
||||
}
|
||||
|
||||
public IGridConnection getConnection() {
|
||||
return this.c;
|
||||
}
|
||||
|
||||
public MEP2PTunnelPart getTunnel() {
|
||||
return this.tunnel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.cache.helpers;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import appeng.parts.p2p.P2PTunnelPart;
|
||||
|
||||
public class TunnelIterator<T extends P2PTunnelPart> implements Iterator<T> {
|
||||
|
||||
private final Iterator<T> wrapped;
|
||||
private final Class targetType;
|
||||
private T Next;
|
||||
|
||||
public TunnelIterator(final Collection<T> tunnelSources, final Class clz) {
|
||||
this.wrapped = tunnelSources.iterator();
|
||||
this.targetType = clz;
|
||||
this.findNext();
|
||||
}
|
||||
|
||||
private void findNext() {
|
||||
while (this.Next == null && this.wrapped.hasNext()) {
|
||||
this.Next = this.wrapped.next();
|
||||
if (!this.targetType.isInstance(this.Next)) {
|
||||
this.Next = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
this.findNext();
|
||||
return this.Next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
final T tmp = this.Next;
|
||||
this.Next = null;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user