use of logisticspipes.interfaces.routing.IFilter in project LogisticsPipes by RS485.
the class PowerSupplierHandler method update.
public void update() {
if (SimpleServiceLocator.cofhPowerProxy.isAvailable() && pipe.getUpgradeManager().hasRFPowerSupplierUpgrade()) {
//Use Buffer
Stream<AdjacentTileEntity> adjacentTileEntityStream = new WorldCoordinatesWrapper(pipe.container).getAdjacentTileEntities();
double globalNeed = 0;
double[] need = new double[(int) adjacentTileEntityStream.count()];
adjacentTileEntityStream = new WorldCoordinatesWrapper(pipe.container).getAdjacentTileEntities();
int i = 0;
Iterator<AdjacentTileEntity> adjacentIt = adjacentTileEntityStream.iterator();
while (adjacentIt.hasNext()) {
AdjacentTileEntity adjacent = adjacentIt.next();
if (SimpleServiceLocator.cofhPowerProxy.isEnergyReceiver(adjacent.tileEntity)) {
if (pipe.canPipeConnect(adjacent.tileEntity, adjacent.direction)) {
ICoFHEnergyReceiver energyReceiver = SimpleServiceLocator.cofhPowerProxy.getEnergyReceiver(adjacent.tileEntity);
ForgeDirection oppositeDir = adjacent.direction.getOpposite();
if (energyReceiver.canConnectEnergy(oppositeDir)) {
globalNeed += need[i] = (energyReceiver.getMaxEnergyStored(oppositeDir) - energyReceiver.getEnergyStored(oppositeDir));
}
}
}
++i;
}
if (globalNeed != 0 && !Double.isNaN(globalNeed)) {
double fullfillable = Math.min(1, internalBufferRF / globalNeed);
i = 0;
adjacentIt = adjacentTileEntityStream.iterator();
while (adjacentIt.hasNext()) {
AdjacentTileEntity adjacent = adjacentIt.next();
if (SimpleServiceLocator.cofhPowerProxy.isEnergyReceiver(adjacent.tileEntity)) {
if (pipe.canPipeConnect(adjacent.tileEntity, adjacent.direction)) {
ICoFHEnergyReceiver energyReceiver = SimpleServiceLocator.cofhPowerProxy.getEnergyReceiver(adjacent.tileEntity);
ForgeDirection oppositeDir = adjacent.direction.getOpposite();
if (energyReceiver.canConnectEnergy(oppositeDir)) {
if (internalBufferRF + 1 < need[i] * fullfillable) {
return;
}
int used = energyReceiver.receiveEnergy(oppositeDir, (int) (need[i] * fullfillable), false);
if (used > 0) {
pipe.container.addLaser(adjacent.direction, 0.5F, LogisticsPowerProviderTileEntity.RF_COLOR, false, true);
internalBufferRF -= used;
}
if (internalBufferRF < 0) {
internalBufferRF = 0;
return;
}
}
}
}
++i;
}
}
//Rerequest Buffer
List<Pair<ISubSystemPowerProvider, List<IFilter>>> provider = pipe.getRouter().getSubSystemPowerProvider();
double available = 0;
outer: for (Pair<ISubSystemPowerProvider, List<IFilter>> pair : provider) {
for (IFilter filter : pair.getValue2()) {
if (filter.blockPower()) {
continue outer;
}
}
if (pair.getValue1().usePaused()) {
continue;
}
if (!pair.getValue1().getBrand().equals("RF")) {
continue;
}
available += pair.getValue1().getPowerLevel();
}
if (available > 0) {
double neededPower = PowerSupplierHandler.INTERNAL_RF_BUFFER_MAX - internalBufferRF;
if (neededPower > 0) {
if (pipe.useEnergy((int) (neededPower / 100), false)) {
outer: for (Pair<ISubSystemPowerProvider, List<IFilter>> pair : provider) {
for (IFilter filter : pair.getValue2()) {
if (filter.blockPower()) {
continue outer;
}
}
if (pair.getValue1().usePaused()) {
continue;
}
if (!pair.getValue1().getBrand().equals("RF")) {
continue;
}
double requestamount = neededPower * (pair.getValue1().getPowerLevel() / available);
pair.getValue1().requestPower(pipe.getRouterId(), requestamount);
}
}
}
}
}
if (SimpleServiceLocator.IC2Proxy.hasIC2() && pipe.getUpgradeManager().getIC2PowerLevel() > 0) {
//Use Buffer
Stream<AdjacentTileEntity> adjacentTileEntityStream = new WorldCoordinatesWrapper(pipe.container).getAdjacentTileEntities();
double globalNeed = 0;
double[] need = new double[(int) adjacentTileEntityStream.count()];
adjacentTileEntityStream = new WorldCoordinatesWrapper(pipe.container).getAdjacentTileEntities();
int i = 0;
Iterator<AdjacentTileEntity> adjacentIt = adjacentTileEntityStream.iterator();
while (adjacentIt.hasNext()) {
AdjacentTileEntity adjacent = adjacentIt.next();
if (SimpleServiceLocator.IC2Proxy.isEnergySink(adjacent.tileEntity)) {
if (pipe.canPipeConnect(adjacent.tileEntity, adjacent.direction)) {
if (SimpleServiceLocator.IC2Proxy.acceptsEnergyFrom(adjacent.tileEntity, pipe.container, adjacent.direction.getOpposite())) {
globalNeed += need[i] = SimpleServiceLocator.IC2Proxy.demandedEnergyUnits(adjacent.tileEntity);
}
}
}
++i;
}
if (globalNeed != 0 && !Double.isNaN(globalNeed)) {
double fullfillable = Math.min(1, internalBufferIC2 / globalNeed);
i = 0;
adjacentIt = adjacentTileEntityStream.iterator();
while (adjacentIt.hasNext()) {
AdjacentTileEntity adjacent = adjacentIt.next();
if (SimpleServiceLocator.IC2Proxy.isEnergySink(adjacent.tileEntity) && pipe.canPipeConnect(adjacent.tileEntity, adjacent.direction) && SimpleServiceLocator.IC2Proxy.acceptsEnergyFrom(adjacent.tileEntity, pipe.container, adjacent.direction.getOpposite())) {
if (internalBufferIC2 + 1 < need[i] * fullfillable) {
return;
}
double toUse = Math.min(pipe.getUpgradeManager().getIC2PowerLevel(), need[i] * fullfillable);
double unUsed = SimpleServiceLocator.IC2Proxy.injectEnergyUnits(adjacent.tileEntity, adjacent.direction.getOpposite(), toUse);
double used = toUse - unUsed;
if (used > 0) {
//MainProxy.sendPacketToAllWatchingChunk(this.pipe.getX(), this.pipe.getZ(), MainProxy.getDimensionForWorld(this.pipe.getWorld()), PacketHandler.getPacket(PowerPacketLaser.class).setColor(LogisticsPowerProviderTileEntity.IC2_COLOR).setPos(this.pipe.getLPPosition()).setRenderBall(true).setDir(adTile.orientation).setLength(0.5F));
pipe.container.addLaser(adjacent.direction, 0.5F, LogisticsPowerProviderTileEntity.IC2_COLOR, false, true);
internalBufferIC2 -= used;
}
if (internalBufferIC2 < 0) {
internalBufferIC2 = 0;
return;
}
}
++i;
}
}
//Rerequest Buffer
List<Pair<ISubSystemPowerProvider, List<IFilter>>> provider = pipe.getRouter().getSubSystemPowerProvider();
double available = 0;
outer: for (Pair<ISubSystemPowerProvider, List<IFilter>> pair : provider) {
for (IFilter filter : pair.getValue2()) {
if (filter.blockPower()) {
continue outer;
}
}
if (pair.getValue1().usePaused()) {
continue;
}
if (!pair.getValue1().getBrand().equals("EU")) {
continue;
}
available += pair.getValue1().getPowerLevel();
}
if (available > 0) {
double neededPower = PowerSupplierHandler.INTERNAL_IC2_BUFFER_MAX - internalBufferIC2;
if (neededPower > 0) {
if (pipe.useEnergy((int) (neededPower / 10000), false)) {
outer: for (Pair<ISubSystemPowerProvider, List<IFilter>> pair : provider) {
for (IFilter filter : pair.getValue2()) {
if (filter.blockPower()) {
continue outer;
}
}
if (pair.getValue1().usePaused()) {
continue;
}
if (!pair.getValue1().getBrand().equals("EU")) {
continue;
}
double requestamount = neededPower * (pair.getValue1().getPowerLevel() / available);
pair.getValue1().requestPower(pipe.getRouterId(), requestamount);
}
}
}
}
}
}
use of logisticspipes.interfaces.routing.IFilter in project LogisticsPipes by RS485.
the class DebugController method handledPipe.
public void handledPipe(boolean flag) {
for (int i = 0; i < closedSet.size(); i++) {
EnumSet<PipeRoutingConnectionType> set = closedSet.get(i);
if (set != null) {
IRouter router = SimpleServiceLocator.routerManager.getRouter(i);
if (router != null) {
MainProxy.sendPacketToPlayer(PacketHandler.getPacket(RoutingUpdateDebugClosedSet.class).setPos(router.getLPPosition()).setSet(set), (EntityPlayer) sender);
}
}
}
for (int i = 0; i < filterList.size(); i++) {
EnumMap<PipeRoutingConnectionType, List<List<IFilter>>> filters = filterList.get(i);
if (filters != null) {
IRouter router = SimpleServiceLocator.routerManager.getRouter(i);
if (router != null) {
MainProxy.sendPacketToPlayer(PacketHandler.getPacket(RoutingUpdateDebugFilters.class).setPos(router.getLPPosition()).setFilters(filters), (EntityPlayer) sender);
}
}
}
ExitRoute[] e = candidatesCost.toArray(new ExitRoute[] {});
if (flag) {
LinkedList<ExitRoute> list = new LinkedList<>();
list.add(nextNode);
list.addAll(Arrays.asList(e));
e = list.toArray(new ExitRoute[] {});
}
MainProxy.sendPacketToPlayer(PacketHandler.getPacket(RoutingUpdateDebugCanidateList.class).setMsg(e), (EntityPlayer) sender);
if (prevNode == null || prevNode.debug.isTraced) {
//Display Information On Client Side
wait("Continue with next pipe?", false);
}
pipeHandled = true;
}
use of logisticspipes.interfaces.routing.IFilter in project LogisticsPipes by RS485.
the class RequestTreeNode method checkCrafting.
private boolean checkCrafting() {
// get all the routers
BitSet routersIndex = ServerRouter.getRoutersInterestedIn(getRequestType());
// get the routing table
List<ExitRoute> validSources = new ArrayList<>();
for (int i = routersIndex.nextSetBit(0); i >= 0; i = routersIndex.nextSetBit(i + 1)) {
IRouter r = SimpleServiceLocator.routerManager.getRouterUnsafe(i, false);
if (!r.isValidCache()) {
//Skip Routers without a valid pipe
continue;
}
List<ExitRoute> e = getRequestType().getRouter().getDistanceTo(r);
if (e != null) {
validSources.addAll(e);
}
}
// distance doesn't matter, because ingredients have to be delivered to the crafter, and we can't tell how long that will take.
workWeightedSorter wSorter = new workWeightedSorter(0);
Collections.sort(validSources, wSorter);
List<Pair<ICraftingTemplate, List<IFilter>>> allCraftersForItem = RequestTreeNode.getCrafters(getRequestType(), validSources);
// if you have a crafter which can make the top treeNode.getStack().getItem()
Iterator<Pair<ICraftingTemplate, List<IFilter>>> iterAllCrafters = allCraftersForItem.iterator();
//a queue to store the crafters, sorted by todo; we will fill up from least-most in a balanced way.
PriorityQueue<CraftingSorterNode> craftersSamePriority = new PriorityQueue<>(5);
ArrayList<CraftingSorterNode> craftersToBalance = new ArrayList<>();
//TODO ^ Make this a generic list
boolean done = false;
Pair<ICraftingTemplate, List<IFilter>> lastCrafter = null;
int currentPriority = 0;
outer: while (!done) {
/// First: Create a list of all crafters with the same priority (craftersSamePriority).
if (iterAllCrafters.hasNext()) {
if (lastCrafter == null) {
lastCrafter = iterAllCrafters.next();
}
} else if (lastCrafter == null) {
done = true;
}
int itemsNeeded = getMissingAmount();
if (lastCrafter != null && (craftersSamePriority.isEmpty() || (currentPriority == lastCrafter.getValue1().getPriority()))) {
currentPriority = lastCrafter.getValue1().getPriority();
Pair<ICraftingTemplate, List<IFilter>> crafter = lastCrafter;
lastCrafter = null;
ICraftingTemplate template = crafter.getValue1();
if (isCrafterUsed(template)) {
continue;
}
if (!template.canCraft(getRequestType())) {
// we this is crafting something else
continue;
}
for (IFilter filter : crafter.getValue2()) {
// is this filtered for some reason.
if (filter.isBlocked() == filter.isFilteredItem(template.getResultItem()) || filter.blockCrafting()) {
continue outer;
}
}
CraftingSorterNode cn = new CraftingSorterNode(crafter, itemsNeeded, root, this);
// if(cn.getWorkSetsAvailableForCrafting()>0)
craftersSamePriority.add(cn);
continue;
}
if (craftersToBalance.isEmpty() && (craftersSamePriority == null || craftersSamePriority.isEmpty())) {
//nothing at this priority was available for crafting
continue;
}
if (craftersSamePriority.size() == 1) {
// then no need to balance.
craftersToBalance.add(craftersSamePriority.poll());
// automatically capped at the real amount of extra work.
craftersToBalance.get(0).addToWorkRequest(itemsNeeded);
} else {
// or the amount of work they have is equal to the next-least busy crafter. then pull the next crafter and repeat.
if (!craftersSamePriority.isEmpty()) {
craftersToBalance.add(craftersSamePriority.poll());
}
// while we crafters that can work and we have work to do.
while (!craftersToBalance.isEmpty() && itemsNeeded > 0) {
// typically pulls 1 at a time, but may pull multiple, if they have the exact same todo.
while (!craftersSamePriority.isEmpty() && craftersSamePriority.peek().currentToDo() <= craftersToBalance.get(0).currentToDo()) {
craftersToBalance.add(craftersSamePriority.poll());
}
// find the most we can add this iteration
int cap;
if (!craftersSamePriority.isEmpty()) {
cap = craftersSamePriority.peek().currentToDo();
} else {
cap = Integer.MAX_VALUE;
}
//split the work between N crafters, up to "cap" (at which point we would be dividing the work between N+1 crafters.
int floor = craftersToBalance.get(0).currentToDo();
cap = Math.min(cap, floor + (itemsNeeded + craftersToBalance.size() - 1) / craftersToBalance.size());
for (CraftingSorterNode crafter : craftersToBalance) {
int request = Math.min(itemsNeeded, cap - floor);
if (request > 0) {
int craftingDone = crafter.addToWorkRequest(request);
// ignored under-crafting
itemsNeeded -= craftingDone;
}
}
}
// all craftersToBalance exhausted, or work completed.
}
// end of else more than 1 crafter at this priority
// commit this work set.
Iterator<CraftingSorterNode> iter = craftersToBalance.iterator();
while (iter.hasNext()) {
CraftingSorterNode c = iter.next();
if (c.stacksOfWorkRequested > 0 && !c.addWorkPromisesToTree()) {
// then it ran out of resources
iter.remove();
}
}
itemsNeeded = getMissingAmount();
if (itemsNeeded <= 0) {
// we have everything we need for this crafting request
break outer;
}
// don't clear, because we might have under-requested, and need to consider these again
if (!craftersToBalance.isEmpty()) {
done = false;
//craftersSamePriority.clear(); // we've extracted all we can from these priority crafters, and we still have more to do, back to the top to get the next priority level.
}
}
//LogisticsPipes.log.info("done");
return isDone();
}
use of logisticspipes.interfaces.routing.IFilter in project LogisticsPipes by RS485.
the class RequestTreeNode method getProviders.
private static List<Pair<IProvide, List<IFilter>>> getProviders(IRouter destination, IResource item) {
// get all the routers
BitSet routersIndex = ServerRouter.getRoutersInterestedIn(item);
// get the routing table
List<ExitRoute> validSources = new ArrayList<>();
for (int i = routersIndex.nextSetBit(0); i >= 0; i = routersIndex.nextSetBit(i + 1)) {
IRouter r = SimpleServiceLocator.routerManager.getRouterUnsafe(i, false);
if (!r.isValidCache()) {
//Skip Routers without a valid pipe
continue;
}
List<ExitRoute> e = destination.getDistanceTo(r);
if (e != null) {
validSources.addAll(e);
}
}
// closer providers are good
Collections.sort(validSources, new workWeightedSorter(1.0));
List<Pair<IProvide, List<IFilter>>> providers = new LinkedList<>();
validSources.stream().filter(r -> r.containsFlag(PipeRoutingConnectionType.canRequestFrom)).forEach(r -> {
CoreRoutedPipe pipe = r.destination.getPipe();
if (pipe instanceof IProvide) {
List<IFilter> list = new LinkedList<>();
list.addAll(r.filters);
providers.add(new Pair<>((IProvide) pipe, list));
}
});
return providers;
}
use of logisticspipes.interfaces.routing.IFilter in project LogisticsPipes by RS485.
the class ModuleCrafter method canProvide.
@Override
public void canProvide(RequestTreeNode tree, RequestTree root, List<IFilter> filters) {
if (!_service.getItemOrderManager().hasExtras() || tree.hasBeenQueried(_service.getItemOrderManager())) {
return;
}
IResource requestedItem = tree.getRequestType();
if (!canCraft(requestedItem)) {
return;
}
for (IFilter filter : filters) {
if (filter.isBlocked() == filter.isFilteredItem(requestedItem) || filter.blockProvider()) {
return;
}
}
int remaining = 0;
for (LogisticsItemOrder extra : _service.getItemOrderManager()) {
if (extra.getType() == ResourceType.EXTRA) {
if (extra.getResource().getItem().equals(requestedItem)) {
remaining += extra.getResource().stack.getStackSize();
}
}
}
remaining -= root.getAllPromissesFor(this, getCraftedItem().getItem());
if (remaining < 1) {
return;
}
if (this.getUpgradeManager().isFuzzyUpgrade() && outputFuzzyFlags.getBitSet().nextSetBit(0) != -1) {
DictResource dict = new DictResource(getCraftedItem(), null).loadFromBitSet(outputFuzzyFlags.getBitSet());
LogisticsExtraDictPromise promise = new LogisticsExtraDictPromise(dict, Math.min(remaining, tree.getMissingAmount()), this, true);
tree.addPromise(promise);
} else {
LogisticsExtraPromise promise = new LogisticsExtraPromise(getCraftedItem().getItem(), Math.min(remaining, tree.getMissingAmount()), this, true);
tree.addPromise(promise);
}
tree.setQueried(_service.getItemOrderManager());
}
Aggregations