Better idling for metatileentities and multiblocks
What: This PR is my attempt on the issue of gregtech machines being "laggy" when actually idling with full inputs and outputs. I've iterated this concept a some times and i think its good so here it is.
How solved: implemented checks in the Abstract recipe logic for inputs (if a valid recipe can be made out of them) and outputs (if its full, and we cant accept a recipe because of it, wait for the output to make some space before looping unsuccessfully) implemented fluid and item handlers that can change those settings by notifying the metatileentity that its inventory changed.
Outcome: GTCE single and multiblock machines will idle with a input of partial ingredients and when its outputs are full.
Additional info: By avoiding recipe lookups when the inputs dont make a valid recipe, and by avoiding simulating merging items that we cant push into the output, we can save some tick time for other stuff
Possible compatibility issue:
Included tests that match the expected behaviour of a chemical reactor ( made by @Exa ) and a blast furnace.
the outputfull is set on the addItemsToItemHandler method, and checked for in the new method shouldSearchForRecipes, so will work immediatelly.
the inputsinvalidation flag should be set o the method that actually returns the Recipe object, and may need implementation on their part, but should not be too much work.
Thanks for updating this. Can you please fix formatting of all edited files as it does not conform our style. IntelliJ IDEA should be able to do it perfectly as we are providing .editorconfig file.
This looks quite solid to me. Anyone from Addons do you see any glaring problems that this could cause to you? Also this is candidate for early sprint merging as it will need lot of testing and would be great to get it finished soon because with every release there are conflicts which needs to be fixed which I believe is quite excruciating.
For addons, this might cause some issues with @DStrand1 's Distinct Input bus implementation found in Gregicality (Initial PR done here https://github.com/Gregicality/gregicality/pull/451), although I will leave it up to him to review this and see if he can rework the distinct bus implementation based on the changes in this PR, and if he has any other concerns.
It may be interesting to implement distinct buses directly in GTCE, as although GTCE multiblocks could not make much use of it, especially since there are no Large Machine Multiblocks as there are in Gregicality, having a unified implementation may make it easier for addons to implement it, and integrate it with the changes done to GTCE logic.
Sorry to be late to the party on this.
I have a few comments, the first is a longish diff. It basically makes 2 changes.
-
It replaces the lists of modified handlers with booleans in MetaTileEntity The only thing that was being done with these lists was x.add(), x.clear() and x.size() > 0 which is isomorphic to x = true, x = false, x == true
-
It makes the passing of the notification handler around more implicit. The handler is only ever "this" currently. Is there a use case where it would be something else? I also think isExport could be implicit as well if isExport() was part of the INotifiableHandler interface and implemented on the 3 handlers from their internal fields. I didn't change this though. Is there any use case where isExportHatch on the multipart bus/hatch doesn't match isExport on the handler?
Here is the diff:
diff --git a/src/main/java/gregtech/api/capability/INotifiableHandler.java b/src/main/java/gregtech/api/capability/INotifiableHandler.java
index 34cf1c36..f6badc9b 100644
--- a/src/main/java/gregtech/api/capability/INotifiableHandler.java
+++ b/src/main/java/gregtech/api/capability/INotifiableHandler.java
@@ -14,12 +14,12 @@ public interface INotifiableHandler {
* @param isExport boolean specifying if a handler is an output handler
*/
- default <T> void addToNotifiedList(MetaTileEntity metaTileEntity, T handler, boolean isExport) {
+ default void addToNotifiedList(MetaTileEntity metaTileEntity, boolean isExport) {
if (metaTileEntity != null && metaTileEntity.isValid()) {
if (isExport) {
- metaTileEntity.addNotifiedOutput(handler);
+ metaTileEntity.addNotifiedOutput(this);
} else {
- metaTileEntity.addNotifiedInput(handler);
+ metaTileEntity.addNotifiedInput(this);
}
}
}
diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java
index c8504522..1048b34b 100755
--- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java
+++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java
@@ -131,13 +131,13 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable
}
protected boolean hasNotifiedInputs() {
- return (metaTileEntity.getNotifiedItemInputList().size() > 0 ||
- metaTileEntity.getNotifiedFluidInputList().size() > 0);
+ return (metaTileEntity.isNotifiedItemInput() ||
+ metaTileEntity.isNotifiedFluidInput());
}
protected boolean hasNotifiedOutputs() {
- return (metaTileEntity.getNotifiedItemOutputList().size() > 0 ||
- metaTileEntity.getNotifiedFluidOutputList().size() > 0);
+ return (metaTileEntity.isNotifiedItemOutput() ||
+ metaTileEntity.isNotifiedFluidOutput());
}
protected boolean canFitNewOutputs() {
@@ -145,8 +145,8 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable
if (this.isOutputsFull && !hasNotifiedOutputs()) return false;
else {
this.isOutputsFull = false;
- metaTileEntity.getNotifiedItemOutputList().clear();
- metaTileEntity.getNotifiedFluidOutputList().clear();
+ metaTileEntity.resetNotifiedItemOutput();
+ metaTileEntity.resetNotifiedFluidOutput();
}
return true;
}
@@ -205,8 +205,8 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable
if (currentRecipe != null && setupAndConsumeRecipeInputs(currentRecipe))
setupRecipe(currentRecipe);
// Inputs have been inspected.
- metaTileEntity.getNotifiedItemInputList().clear();
- metaTileEntity.getNotifiedFluidInputList().clear();
+ metaTileEntity.resetNotifiedItemInput();
+ metaTileEntity.resetNotifiedFluidInput();
}
public void forceRecipeRecheck() {
@@ -235,8 +235,8 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable
@Deprecated
protected boolean checkRecipeInputsDirty(IItemHandler inputs, IMultipleTankHandler fluidInputs) {
boolean isDirty = this.hasNotifiedInputs();
- metaTileEntity.getNotifiedItemInputList().clear();
- metaTileEntity.getNotifiedFluidInputList().clear();
+ metaTileEntity.resetNotifiedItemInput();
+ metaTileEntity.resetNotifiedFluidInput();
return isDirty;
}
diff --git a/src/main/java/gregtech/api/capability/impl/NotifiableFilteredFluidHandler.java b/src/main/java/gregtech/api/capability/impl/NotifiableFilteredFluidHandler.java
index 7e5d3ab4..db4ee451 100644
--- a/src/main/java/gregtech/api/capability/impl/NotifiableFilteredFluidHandler.java
+++ b/src/main/java/gregtech/api/capability/impl/NotifiableFilteredFluidHandler.java
@@ -17,7 +17,7 @@ public class NotifiableFilteredFluidHandler extends FilteredFluidHandler impleme
@Override
protected void onContentsChanged() {
super.onContentsChanged();
- addToNotifiedList(notifiableEntity, this, isExport);
+ addToNotifiedList(notifiableEntity, isExport);
}
@Override
diff --git a/src/main/java/gregtech/api/capability/impl/NotifiableFluidTank.java b/src/main/java/gregtech/api/capability/impl/NotifiableFluidTank.java
index 2c54e096..9aa141e4 100644
--- a/src/main/java/gregtech/api/capability/impl/NotifiableFluidTank.java
+++ b/src/main/java/gregtech/api/capability/impl/NotifiableFluidTank.java
@@ -18,7 +18,7 @@ public class NotifiableFluidTank extends FluidTank implements INotifiableHandler
@Override
protected void onContentsChanged() {
super.onContentsChanged();
- addToNotifiedList(notifiableEntity, this, isExport);
+ addToNotifiedList(notifiableEntity, isExport);
}
@Override
diff --git a/src/main/java/gregtech/api/capability/impl/NotifiableItemStackHandler.java b/src/main/java/gregtech/api/capability/impl/NotifiableItemStackHandler.java
index 88e3c58e..4858287e 100644
--- a/src/main/java/gregtech/api/capability/impl/NotifiableItemStackHandler.java
+++ b/src/main/java/gregtech/api/capability/impl/NotifiableItemStackHandler.java
@@ -17,9 +17,9 @@ public class NotifiableItemStackHandler extends ItemStackHandler implements IIte
}
@Override
- public void onContentsChanged(int slot) {
+ protected void onContentsChanged(int slot) {
super.onContentsChanged(slot);
- addToNotifiedList(notifiableEntity, this, isExport);
+ addToNotifiedList(notifiableEntity, isExport);
}
@Override
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 2c457529..d94462d4 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -88,10 +88,10 @@ public abstract class MetaTileEntity implements ICoverable {
protected boolean isFragile = false;
private final CoverBehavior[] coverBehaviors = new CoverBehavior[6];
- protected List<IItemHandlerModifiable> notifiedItemOutputList = new ArrayList<>();
- protected List<IItemHandlerModifiable> notifiedItemInputList = new ArrayList<>();
- protected List<IFluidHandler> notifiedFluidInputList = new ArrayList<>();
- protected List<IFluidHandler> notifiedFluidOutputList = new ArrayList<>();
+ protected boolean notifiedItemOutput = false;
+ protected boolean notifiedItemInput = false;
+ protected boolean notifiedFluidInput = false;
+ protected boolean notifiedFluidOutput = false;
public MetaTileEntity(ResourceLocation metaTileEntityId) {
this.metaTileEntityId = metaTileEntityId;
@@ -261,25 +261,17 @@ public abstract class MetaTileEntity implements ICoverable {
public <T> void addNotifiedInput(T input) {
if (input instanceof IItemHandlerModifiable) {
- if (!notifiedItemInputList.contains(input)) {
- this.notifiedItemInputList.add((IItemHandlerModifiable) input);
- }
+ this.notifiedItemInput = true;
} else if (input instanceof FluidTank) {
- if (!notifiedFluidInputList.contains(input)) {
- this.notifiedFluidInputList.add((FluidTank) input);
- }
+ this.notifiedFluidInput = true;
}
}
public <T> void addNotifiedOutput(T output) {
if (output instanceof IItemHandlerModifiable) {
- if (!notifiedItemOutputList.contains(output)) {
- this.notifiedItemOutputList.add((IItemHandlerModifiable) output);
- }
+ this.notifiedItemOutput = true;
} else if (output instanceof NotifiableFluidTank) {
- if (!notifiedFluidOutputList.contains(output)) {
- this.notifiedFluidOutputList.add((NotifiableFluidTank) output);
- }
+ this.notifiedFluidOutput = true;
}
}
@@ -1239,20 +1231,36 @@ public abstract class MetaTileEntity implements ICoverable {
return exportFluids;
}
- public List<IItemHandlerModifiable> getNotifiedItemOutputList() {
- return notifiedItemOutputList;
+ public boolean isNotifiedItemOutput() {
+ return this.notifiedItemOutput;
+ }
+
+ public boolean isNotifiedItemInput() {
+ return this.notifiedItemInput;
+ }
+
+ public boolean isNotifiedFluidInput() {
+ return this.notifiedFluidInput;
+ }
+
+ public boolean isNotifiedFluidOutput() {
+ return this.notifiedFluidOutput;
+ }
+
+ public void resetNotifiedItemOutput() {
+ this.notifiedItemOutput = false;
}
- public List<IItemHandlerModifiable> getNotifiedItemInputList() {
- return notifiedItemInputList;
+ public void resetNotifiedItemInput() {
+ this.notifiedItemInput = false;
}
- public List<IFluidHandler> getNotifiedFluidInputList() {
- return notifiedFluidInputList;
+ public void resetNotifiedFluidInput() {
+ this.notifiedFluidInput = false;
}
- public List<IFluidHandler> getNotifiedFluidOutputList() {
- return notifiedFluidOutputList;
+ public void resetNotifiedFluidOutput() {
+ this.notifiedFluidOutput = false;
}
public boolean isFragile() {
diff --git a/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityFluidHatch.java
index 1664c39e..526ce7aa 100644
--- a/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityFluidHatch.java
+++ b/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityFluidHatch.java
@@ -130,7 +130,7 @@ public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockPart imple
}
if (handler != null) {
handler.setNotifiableMetaTileEntity(metaTileEntity);
- handler.addToNotifiedList(this, handler, isExportHatch);
+ handler.addToNotifiedList(this, this.isExportHatch);
}
}
diff --git a/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityItemBus.java
index 39783c00..fe52029d 100644
--- a/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityItemBus.java
+++ b/src/main/java/gregtech/common/metatileentities/electric/multiblockpart/MetaTileEntityItemBus.java
@@ -99,7 +99,7 @@ public class MetaTileEntityItemBus extends MetaTileEntityMultiblockPart implemen
}
if (handler != null) {
handler.setNotifiableMetaTileEntity(metaTileEntity);
- handler.addToNotifiedList(this, handler, isExportHatch);
+ handler.addToNotifiedList(this, this.isExportHatch);
}
}
diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiFurnace.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiFurnace.java
index 1651bc56..c6e18997 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiFurnace.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiFurnace.java
@@ -126,7 +126,7 @@ public class MetaTileEntityMultiFurnace extends RecipeMapMultiblockController {
if (currentRecipe != null && setupAndConsumeRecipeInputs(currentRecipe))
setupRecipe(currentRecipe);
// Inputs have been inspected.
- metaTileEntity.getNotifiedItemInputList().clear();
+ metaTileEntity.resetNotifiedItemInput();
}
@Override
Unfortunately, I don't know much about the AbstractRecipeLogic class which is the important change in this PR. So I can't really offer any insights there.