diff --git a/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java index e7a7ed06..8b99451a 100644 --- a/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java @@ -30,24 +30,25 @@ public class GuiFluidLevelMaintainer extends AEBaseGui { super(new ContainerFluidLevelMaintainer(ipl, tile)); this.cont = (ContainerFluidLevelMaintainer) inventorySlots; this.ySize = 214; - for (int i = 0; i < TileFluidLevelMaintainer.MAX_FLUID; i ++) { - maintain[i] = new GuiNumberBox(this.fontRenderer, this.guiLeft + 39, this.guiTop + 22 + i * 20, 42, 10, Integer.class); - request[i] = new GuiNumberBox(this.fontRenderer, this.guiLeft + 102, this.guiTop + 22 + i * 20, 42, 10, Integer.class); - } + } + + public void setMaintainNumber(int id, int size) { + if (id < 0 || id >= TileFluidLevelMaintainer.MAX_FLUID || size < 0) + return; + this.maintain[id].setText(String.valueOf(size)); } @Override - protected void renderHoveredToolTip(int p_191948_1_, int p_191948_2_) - { + protected void renderHoveredToolTip(int x, int y) { if (this.mc.player.inventory.getItemStack().isEmpty() && this.getSlotUnderMouse() != null && this.getSlotUnderMouse().getHasStack() && this.getSlotUnderMouse() instanceof ContainerFluidLevelMaintainer.DisplayFluidSlot) { ItemStack packet = this.getSlotUnderMouse().getStack(); FluidStack fluid = ItemFluidPacket.getFluidStack(packet); - this.renderToolTip(ItemFluidPacket.newDisplayStack(fluid), p_191948_1_, p_191948_2_); + this.renderToolTip(ItemFluidPacket.newDisplayStack(fluid), x, y); } else { - super.renderHoveredToolTip(p_191948_1_, p_191948_2_); + super.renderHoveredToolTip(x, y); } } @@ -91,7 +92,8 @@ public class GuiFluidLevelMaintainer extends AEBaseGui { result = 1; } - FluidCraft.proxy.netHandler.sendToServer(new CPacketUpdateFluidLevel(id, (int) result)); + if (id >= 10 || result != 0) + FluidCraft.proxy.netHandler.sendToServer(new CPacketUpdateFluidLevel(id, (int) result)); } catch (NumberFormatException ignored) { } @@ -107,6 +109,12 @@ public class GuiFluidLevelMaintainer extends AEBaseGui { @Override public void initGui() { super.initGui(); + for (int i = 0; i < TileFluidLevelMaintainer.MAX_FLUID; i ++) { + maintain[i] = new GuiNumberBox(this.fontRenderer, this.guiLeft + 39, this.guiTop + 22 + i * 20, 42, 10, Integer.class); + request[i] = new GuiNumberBox(this.fontRenderer, this.guiLeft + 102, this.guiTop + 22 + i * 20, 42, 10, Integer.class); + maintain[i].setTextColor(16777215); + request[i].setTextColor(16777215); + } TileFluidLevelMaintainer tile = this.cont.getTile(); IItemHandler inv = tile.getInventoryHandler(); for (int i = 0; i < inv.getSlots(); i ++) { @@ -147,5 +155,9 @@ public class GuiFluidLevelMaintainer extends AEBaseGui { public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) { mc.getTextureManager().bindTexture(TEX_BG); drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize); + for (int i = 0; i < TileFluidLevelMaintainer.MAX_FLUID ; i ++) { + this.maintain[i].drawTextBox(); + this.request[i].drawTextBox(); + } } } diff --git a/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java index 1f18cab9..2aab4006 100644 --- a/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java @@ -4,12 +4,16 @@ import appeng.container.AEBaseContainer; import appeng.container.slot.SlotFake; import appeng.helpers.InventoryAction; import appeng.tile.inventory.AppEngInternalAEInventory; +import com.glodblock.github.FluidCraft; import com.glodblock.github.common.item.ItemFluidPacket; import com.glodblock.github.common.tile.TileFluidLevelMaintainer; +import com.glodblock.github.network.SPacketSetFluidLevel; +import com.glodblock.github.util.Util; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.items.IItemHandler; @@ -40,6 +44,8 @@ public class ContainerFluidLevelMaintainer extends AEBaseContainer { Slot slot = getSlot(slotId); if (slot instanceof DisplayFluidSlot) { final ItemStack stack = player.inventory.getItemStack(); + FluidStack fluid = Util.getFluidFromItem(stack); + FluidCraft.proxy.netHandler.sendTo(new SPacketSetFluidLevel(slotId, fluid == null ? 0 : fluid.amount), player); slot.putStack(stack.isEmpty() ? stack : stack.copy()); } else { super.doAction(player, action, slotId, id); diff --git a/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java index e72fe0c0..d985d69c 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java @@ -7,20 +7,18 @@ import appeng.api.networking.GridFlags; import appeng.api.networking.crafting.ICraftingLink; import appeng.api.networking.crafting.ICraftingRequester; import appeng.api.networking.energy.IEnergyGrid; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.api.networking.events.MENetworkStorageEvent; import appeng.api.networking.security.IActionSource; -import appeng.api.networking.storage.IStackWatcher; -import appeng.api.networking.storage.IStackWatcherHost; import appeng.api.networking.storage.IStorageGrid; import appeng.api.storage.IMEMonitor; -import appeng.api.storage.IStorageChannel; import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; -import appeng.api.storage.data.IAEStack; -import appeng.api.storage.data.IItemList; import appeng.core.AELog; import appeng.fluids.util.AEFluidStack; -import appeng.helpers.MultiCraftingTracker; import appeng.helpers.Reflected; import appeng.me.GridAccessException; import appeng.me.helpers.MachineSource; @@ -31,6 +29,7 @@ import appeng.util.inv.InvOperation; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidPacket; import com.glodblock.github.util.DummyInvAdaptor; +import com.glodblock.github.util.MultiCraftingTracker; import com.google.common.collect.ImmutableSet; import io.netty.buffer.ByteBuf; import net.minecraft.item.ItemStack; @@ -42,7 +41,7 @@ import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; import java.io.IOException; -public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWatcherHost, ICraftingRequester, IAEAppEngInventory { +public class TileFluidLevelMaintainer extends AENetworkTile implements ICraftingRequester, IAEAppEngInventory { public static final int MAX_FLUID = 5; @@ -59,8 +58,6 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat }; private final MultiCraftingTracker craftingTracker = new MultiCraftingTracker(this, MAX_FLUID); private final long[] request = new long[MAX_FLUID]; - private final long[] reportValue = new long[MAX_FLUID]; - private IStackWatcher watcher; private final IActionSource source; @Reflected @@ -70,15 +67,8 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat this.source = new MachineSource( this ); } - public void setConfig(int id, IAEItemStack item) { - if (id < 0 || id > MAX_FLUID) { - return; - } - this.config.setStackInSlot(id, item.getDefinition()); - } - public void setConfig(int id, int size) { - if (id < 0 || id > MAX_FLUID || this.config.getStackInSlot(id).isEmpty()) { + if (id < 0 || id >= MAX_FLUID || this.config.getStackInSlot(id).isEmpty()) { return; } ItemStack packet = this.config.getStackInSlot(id); @@ -86,13 +76,16 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat if (copy != null) copy.amount = size; this.config.setStackInSlot(id, ItemFluidPacket.newStack(copy)); + doWork(); } public void setRequest(int id, long amount) { - if (id < 0 || id > MAX_FLUID) { + if (id < 0 || id >= MAX_FLUID || amount < 0) { return; } this.request[id] = amount; + markForUpdate(); + doWork(); } public IItemHandler getInventoryHandler() { @@ -103,6 +96,46 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat return this.request; } + @MENetworkEventSubscribe + public void onStorageUpdate(MENetworkStorageEvent event) { + if (event.channel.equals(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class))) { + doWork(); + } + } + + @MENetworkEventSubscribe + public void onPowerUpdate(MENetworkPowerStatusChange event) { + doWork(); + } + + @MENetworkEventSubscribe + public void onChannelUpdate(MENetworkChannelsChanged event) { + doWork(); + } + + public void doWork() { + if (!getProxy().isActive()) { + return; + } + IMEMonitor storage = getFluidMonitor(); + try { + for (int i = 0; i < MAX_FLUID; i ++) { + IAEItemStack packet = this.config.getAEStackInSlot(i); + FluidStack fluid = ItemFluidPacket.getFluidStack(packet); + if (fluid != null && fluid.amount > 0) { + IAEFluidStack remain = storage.extractItems(AEFluidStack.fromFluidStack(fluid), Actionable.SIMULATE, this.source); + if (remain == null || remain.getStackSize() < fluid.amount) { + FluidStack copy = fluid.copy(); + copy.amount = (int) request[i]; + System.out.print(this.craftingTracker.handleCrafting(i, request[i], ItemFluidDrop.newAeStack(copy), DummyInvAdaptor.INSTANCE, getWorld(), getProxy().getGrid(), getProxy().getCrafting(), this.source) + "\n"); + } + } + } + } catch (GridAccessException e) { + //Ignore + } + } + @Override protected boolean readFromStream(ByteBuf data) throws IOException { boolean changed = super.readFromStream(data); @@ -113,6 +146,9 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat changed = true; } } + for (int i = 0; i < MAX_FLUID; i ++) { + request[i] = data.readLong(); + } return changed; } @@ -122,14 +158,16 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat for (int i = 0; i < config.getSlots(); i++) { ByteBufUtils.writeItemStack(data, config.getStackInSlot(i)); } + for (int i = 0; i < MAX_FLUID; i ++) { + data.writeLong(request[i]); + } } @Override public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); for (int i = 0; i < MAX_FLUID; i ++) { - request[i] = data.getLong("req" + i); - reportValue[i] = data.getLong("rep" + i); + request[i] = data.getLong("reqX" + i); } config.readFromNBT(data, "configX"); craftingTracker.readFromNBT(data); @@ -139,8 +177,7 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); for (int i = 0; i < MAX_FLUID; i ++) { - data.setLong("req" + i, request[i]); - data.setLong("rep" + i, reportValue[i]); + data.setLong("reqX" + i, request[i]); } config.writeToNBT(data, "configX"); craftingTracker.writeToNBT(data); @@ -209,46 +246,6 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat this.craftingTracker.jobStateChange( link ); } - @Override - public void updateWatcher(IStackWatcher iWatcher) { - this.watcher = iWatcher; - configureWatchers(); - } - - public void configureWatchers() { - if (this.watcher != null) { - watcher.reset(); - for (int i = 0; i < MAX_FLUID; i ++ ) { - if (this.config.getAEStackInSlot(i) != null && !this.config.getAEStackInSlot(i).getDefinition().isEmpty()) { - IAEItemStack packet = this.config.getAEStackInSlot(i); - watcher.add(ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(packet))); - } - } - } - } - - @Override - public void onStackChange(IItemList iItemList, IAEStack fullStack, IAEStack diffStack, IActionSource src, IStorageChannel chan) { - if (chan == AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class) && fullStack instanceof IAEFluidStack) { - for (int i = 0; i < MAX_FLUID; i ++) { - try { - IAEItemStack packet = this.config.getAEStackInSlot(i); - IAEFluidStack fluid = AEFluidStack.fromFluidStack(ItemFluidPacket.getFluidStack(packet)); - if (fluid != null && fluid.getFluidStack() != null - && fluid.getFluidStack().isFluidEqual(((IAEFluidStack)diffStack).getFluidStack())) { - this.reportValue[i] = fullStack.getStackSize(); - IAEItemStack drops = ItemFluidDrop.newAeStack(fluid); - if (drops != null && this.reportValue[i] < drops.getStackSize()) { - this.craftingTracker.handleCrafting(i, request[i], drops, DummyInvAdaptor.INSTANCE, this.world, this.getProxy().getGrid(), this.getProxy().getCrafting(), this.source ); - } - } - } catch (GridAccessException e) { - // Ignore - } - } - } - } - @Override public void onChangeInventory(IItemHandler iItemHandler, int i, InvOperation invOperation, ItemStack itemStack, ItemStack itemStack1) { markForUpdate(); diff --git a/src/main/java/com/glodblock/github/loader/ChannelLoader.java b/src/main/java/com/glodblock/github/loader/ChannelLoader.java index 2cdbd68d..816b0851 100644 --- a/src/main/java/com/glodblock/github/loader/ChannelLoader.java +++ b/src/main/java/com/glodblock/github/loader/ChannelLoader.java @@ -16,6 +16,7 @@ public class ChannelLoader implements Runnable { FluidCraft.proxy.netHandler.registerMessage(new CPacketEncodePattern.Handler(), CPacketEncodePattern.class, id ++, Side.SERVER); FluidCraft.proxy.netHandler.registerMessage(new CPacketLoadPattern.Handler(), CPacketLoadPattern.class, id ++, Side.SERVER); FluidCraft.proxy.netHandler.registerMessage(new CPacketUpdateFluidLevel.Handler(), CPacketUpdateFluidLevel.class, id ++, Side.SERVER); + FluidCraft.proxy.netHandler.registerMessage(new SPacketSetFluidLevel.Handler(), SPacketSetFluidLevel.class, id ++, Side.CLIENT); } } diff --git a/src/main/java/com/glodblock/github/network/CPacketUpdateFluidLevel.java b/src/main/java/com/glodblock/github/network/CPacketUpdateFluidLevel.java index 998c1910..30231740 100644 --- a/src/main/java/com/glodblock/github/network/CPacketUpdateFluidLevel.java +++ b/src/main/java/com/glodblock/github/network/CPacketUpdateFluidLevel.java @@ -45,7 +45,7 @@ public class CPacketUpdateFluidLevel implements IMessage { player.getServerWorld().addScheduledTask(() -> { if (player.openContainer instanceof ContainerFluidLevelMaintainer) { TileFluidLevelMaintainer te = ((ContainerFluidLevelMaintainer) player.openContainer).getTile(); - if (message.index > 10) { + if (message.index >= 10) { te.setRequest(message.index - 10, message.size); } else { diff --git a/src/main/java/com/glodblock/github/network/SPacketSetFluidLevel.java b/src/main/java/com/glodblock/github/network/SPacketSetFluidLevel.java new file mode 100644 index 00000000..fd90709c --- /dev/null +++ b/src/main/java/com/glodblock/github/network/SPacketSetFluidLevel.java @@ -0,0 +1,55 @@ +package com.glodblock.github.network; + +import com.glodblock.github.client.GuiFluidLevelMaintainer; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; + +import javax.annotation.Nullable; + +public class SPacketSetFluidLevel implements IMessage { + + private int index; + private int size; + + public SPacketSetFluidLevel() { + //NO-OP + } + + public SPacketSetFluidLevel(int id, int value) { + this.index = id; + this.size = value; + } + + @Override + public void fromBytes(ByteBuf buf) { + index = buf.readInt(); + size = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(index); + buf.writeInt(size); + } + + public static class Handler implements IMessageHandler { + + @Nullable + @Override + public IMessage onMessage(SPacketSetFluidLevel message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(() -> { + final GuiScreen gs = Minecraft.getMinecraft().currentScreen; + if (gs instanceof GuiFluidLevelMaintainer) { + ((GuiFluidLevelMaintainer) gs).setMaintainNumber(message.index, message.size); + } + }); + return null; + } + + } + +} diff --git a/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java b/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java index 464a50ce..f688857c 100644 --- a/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java +++ b/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java @@ -37,12 +37,12 @@ public class DummyInvAdaptor extends InventoryAdaptor { @Override public ItemStack addItems(ItemStack itemStack) { - return null; + return ItemStack.EMPTY; } @Override public ItemStack simulateAdd(ItemStack itemStack) { - return null; + return ItemStack.EMPTY; } @Override diff --git a/src/main/java/com/glodblock/github/util/MultiCraftingTracker.java b/src/main/java/com/glodblock/github/util/MultiCraftingTracker.java new file mode 100644 index 00000000..deaeed54 --- /dev/null +++ b/src/main/java/com/glodblock/github/util/MultiCraftingTracker.java @@ -0,0 +1,254 @@ +package com.glodblock.github.util; + +import appeng.api.AEApi; +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.*; +import appeng.api.networking.security.IActionSource; +import appeng.api.storage.data.IAEItemStack; +import appeng.helpers.NonNullArrayIterator; +import appeng.util.InventoryAdaptor; +import com.google.common.collect.ImmutableSet; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class MultiCraftingTracker { + private final int size; + private final ICraftingRequester owner; + + private Future[] jobs = null; + private ICraftingLink[] links = null; + + public MultiCraftingTracker( final ICraftingRequester o, final int size ) + { + this.owner = o; + this.size = size; + } + + public void readFromNBT( final NBTTagCompound extra ) + { + for( int x = 0; x < this.size; x++ ) + { + final NBTTagCompound link = extra.getCompoundTag( "links-" + x ); + + if(!link.isEmpty()) + { + this.setLink( x, AEApi.instance().storage().loadCraftingLink( link, this.owner ) ); + } + } + } + + public void writeToNBT( final NBTTagCompound extra ) + { + for( int x = 0; x < this.size; x++ ) + { + final ICraftingLink link = this.getLink( x ); + + if( link != null ) + { + final NBTTagCompound ln = new NBTTagCompound(); + link.writeToNBT( ln ); + extra.setTag( "links-" + x, ln ); + } + } + } + + public boolean handleCrafting(int x, long itemToCraft, IAEItemStack ais, InventoryAdaptor d, World w, IGrid g, ICraftingGrid cg, IActionSource mySrc) { + if (ais != null) { + ItemStack inputStack = ais.getCachedItemStack(ais.getStackSize()); + ItemStack remaining = d.simulateAdd(inputStack); + + if (remaining.isEmpty()) { + ais.setCachedItemStack(inputStack); + Future craftingJob = this.getJob(x); + + if (this.getLink(x) != null) { + return false; + } + + if (craftingJob == null && this.getLink(x) == null) { + IAEItemStack aisC = ais.copy(); + aisC.setStackSize(itemToCraft); + this.setJob(x, cg.beginCraftingJob(w, g, mySrc, aisC, null)); + craftingJob = this.getJob(x); + } + + if (craftingJob == null) { + return false; + } + + try { + ICraftingJob job = craftingJob.get(); + + if (job != null) { + ICraftingLink link = cg.submitJob(job, this.owner, null, false, mySrc); + this.setJob(x, null); + if (link != null) { + this.setLink(x, link); + return true; + } + } + } catch (InterruptedException | ExecutionException ignored) { + } + } else { + ais.setCachedItemStack(remaining); + } + } + + return false; + } + + public ImmutableSet getRequestedJobs() + { + if( this.links == null ) + { + return ImmutableSet.of(); + } + + return ImmutableSet.copyOf( new NonNullArrayIterator<>( this.links ) ); + } + + public void jobStateChange( final ICraftingLink link ) + { + if( this.links != null ) + { + for( int x = 0; x < this.links.length; x++ ) + { + if( this.links[x] == link ) + { + this.setLink( x, null ); + return; + } + } + } + } + + int getSlot( final ICraftingLink link ) + { + if( this.links != null ) + { + for( int x = 0; x < this.links.length; x++ ) + { + if( this.links[x] == link ) + { + return x; + } + } + } + + return -1; + } + + void cancel() + { + if( this.links != null ) + { + for( final ICraftingLink l : this.links ) + { + if( l != null ) + { + l.cancel(); + } + } + + this.links = null; + } + + if( this.jobs != null ) + { + for( final Future l : this.jobs ) + { + if( l != null ) + { + l.cancel( true ); + } + } + + this.jobs = null; + } + } + + boolean isBusy( final int slot ) + { + return this.getLink( slot ) != null || this.getJob( slot ) != null; + } + + private ICraftingLink getLink( final int slot ) + { + if( this.links == null ) + { + return null; + } + + return this.links[slot]; + } + + private void setLink( final int slot, final ICraftingLink l ) + { + if( this.links == null ) + { + this.links = new ICraftingLink[this.size]; + } + + this.links[slot] = l; + + boolean hasStuff = false; + for( int x = 0; x < this.links.length; x++ ) + { + final ICraftingLink g = this.links[x]; + + if( g == null || g.isCanceled() || g.isDone() ) + { + this.links[x] = null; + } + else + { + hasStuff = true; + } + } + + if( !hasStuff ) + { + this.links = null; + } + } + + private Future getJob( final int slot ) + { + if( this.jobs == null ) + { + return null; + } + + return this.jobs[slot]; + } + + @SuppressWarnings("unchecked") + private void setJob( final int slot, final Future l ) + { + if( this.jobs == null ) + { + this.jobs = new Future[this.size]; + } + + this.jobs[slot] = l; + + boolean hasStuff = false; + + for( final Future job : this.jobs ) + { + if (job != null) { + hasStuff = true; + break; + } + } + + if( !hasStuff ) + { + this.jobs = null; + } + } +}