-
-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bugfix/#758 concurrency issue #1025
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,8 @@ | |
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
import java.util.Queue; | ||
import java.util.concurrent.ConcurrentLinkedQueue; | ||
import java.util.function.Predicate; | ||
|
||
/** | ||
|
@@ -28,9 +29,9 @@ | |
public class TileEntityWareHouse extends TileEntityColonyBuilding | ||
{ | ||
/** | ||
* List which contains the currentTasks to be executed by the deliveryman. | ||
* Queue which contains the currentTasks to be executed by the deliveryman. | ||
*/ | ||
private final CopyOnWriteArrayList<AbstractBuilding> list = new CopyOnWriteArrayList<>(); | ||
private final Queue<AbstractBuilding> taskQueue = new ConcurrentLinkedQueue<>(); | ||
|
||
/** | ||
* Wait this amount of ticks before checking again. | ||
|
@@ -92,10 +93,10 @@ public void update() | |
if (i == index) | ||
{ | ||
if(buildingEntry.getValue() instanceof AbstractBuildingWorker | ||
&& !list.contains(buildingEntry.getValue()) | ||
&& ((AbstractBuildingWorker) buildingEntry.getValue()).needsAnything()) | ||
&& !taskQueue.contains(buildingEntry.getValue()) | ||
&& (buildingEntry.getValue()).needsAnything()) | ||
{ | ||
checkInWareHouse((AbstractBuildingWorker) buildingEntry.getValue(), true); | ||
checkInWareHouse(buildingEntry.getValue(), true); | ||
} | ||
else if(buildingEntry.getValue() instanceof BuildingHome && ((BuildingHome) buildingEntry.getValue()).isFoodNeeded()) | ||
{ | ||
|
@@ -117,32 +118,28 @@ public boolean checkInWareHouseForFood(final BuildingHome buildingEntry, final b | |
if (addToList) | ||
{ | ||
buildingEntry.setOnGoingDelivery(true); | ||
list.add(buildingEntry); | ||
taskQueue.add(buildingEntry); | ||
} | ||
return true; | ||
} | ||
|
||
if (list.contains(buildingEntry)) | ||
if (taskQueue.contains(buildingEntry)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
list.remove(buildingEntry); | ||
taskQueue.remove(buildingEntry); | ||
buildingEntry.setOnGoingDelivery(false); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Get the first task in the list. | ||
* Get the first task in the taskQueue, or null if its empty. | ||
* @return the building which needs a delivery. | ||
*/ | ||
@Nullable | ||
public AbstractBuilding getTask() | ||
{ | ||
if(list.isEmpty()) | ||
{ | ||
return null; | ||
} | ||
return list.remove(0); | ||
return taskQueue.poll(); | ||
} | ||
|
||
/** | ||
|
@@ -155,7 +152,7 @@ public boolean checkInWareHouse(@NotNull final AbstractBuilding buildingEntry, b | |
{ | ||
if(buildingEntry.areItemsNeeded()) | ||
{ | ||
for(final ItemStack stack : buildingEntry.getNeededItems()) | ||
for(final ItemStack stack : buildingEntry.getCopyOfNeededItems()) | ||
{ | ||
if(stack == null | ||
|| (deliveryManHasBuildingAsTask(buildingEntry) | ||
|
@@ -169,14 +166,15 @@ public boolean checkInWareHouse(@NotNull final AbstractBuilding buildingEntry, b | |
if(addToList) | ||
{ | ||
buildingEntry.setOnGoingDelivery(true); | ||
list.add(buildingEntry); | ||
taskQueue.add(buildingEntry); | ||
} | ||
return true; | ||
} | ||
} | ||
if (list.contains(buildingEntry)) | ||
|
||
if (taskQueue.contains(buildingEntry)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
list.remove(buildingEntry); | ||
taskQueue.remove(buildingEntry); | ||
buildingEntry.setOnGoingDelivery(false); | ||
} | ||
} | ||
|
@@ -189,13 +187,14 @@ public boolean checkInWareHouse(@NotNull final AbstractBuilding buildingEntry, b | |
if (addToList) | ||
{ | ||
buildingEntry.setOnGoingDelivery(true); | ||
list.add(buildingEntry); | ||
taskQueue.add(buildingEntry); | ||
} | ||
return true; | ||
} | ||
if (list.contains(buildingEntry)) | ||
|
||
if (taskQueue.contains(buildingEntry)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
list.remove(buildingEntry); | ||
taskQueue.remove(buildingEntry); | ||
buildingEntry.setOnGoingDelivery(false); | ||
} | ||
} | ||
|
@@ -234,35 +233,17 @@ private boolean deliveryManHasBuildingAsTask(@NotNull final AbstractBuilding bui | |
* @param is the type of item requested (amount is ignored) | ||
* @return true if a stack of that type was found | ||
*/ | ||
public boolean isInHut(@Nullable final ItemStack is) | ||
private boolean isInHut(@Nullable final ItemStack is) | ||
{ | ||
@Nullable final AbstractBuilding building = getBuilding(); | ||
if(building != null) | ||
{ | ||
if(isInTileEntity(building.getTileEntity(), is)) | ||
{ | ||
return true; | ||
} | ||
|
||
for(final BlockPos pos : building.getAdditionalCountainers()) | ||
{ | ||
@Nullable final TileEntity entity = world.getTileEntity(pos); | ||
if(entity instanceof TileEntityChest && isInTileEntity((TileEntityChest) entity, is)) | ||
{ | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
return is != null && isInHut(stack -> stack != null && is.isItemEqual(stack)); | ||
} | ||
|
||
/** | ||
* Check all chests in the worker hut for a required item. | ||
* @param itemStackSelectionPredicate the type of item requested (amount is ignored). | ||
* @return true if a stack of that type was found | ||
*/ | ||
public boolean isInHut(@NotNull final Predicate<ItemStack> itemStackSelectionPredicate) | ||
private boolean isInHut(@NotNull final Predicate<ItemStack> itemStackSelectionPredicate) | ||
{ | ||
@Nullable final AbstractBuilding building = getBuilding(); | ||
if(building != null) | ||
|
@@ -287,31 +268,13 @@ public boolean isInHut(@NotNull final Predicate<ItemStack> itemStackSelectionPre | |
|
||
/** | ||
* Check for a certain item and return the position of the chest containing it. | ||
* @param stack the stack to search for. | ||
* @param is the stack to search for. | ||
* @return the position or null. | ||
*/ | ||
@Nullable | ||
public BlockPos getPositionOfChestWithItemStack(@NotNull final ItemStack stack) | ||
public BlockPos getPositionOfChestWithItemStack(@NotNull final ItemStack is) | ||
{ | ||
@Nullable final AbstractBuilding building = getBuilding(); | ||
|
||
if(building != null) | ||
{ | ||
if(isInTileEntity(building.getTileEntity(), stack)) | ||
{ | ||
return building.getLocation(); | ||
} | ||
|
||
for(final BlockPos pos : building.getAdditionalCountainers()) | ||
{ | ||
final TileEntity entity = world.getTileEntity(pos); | ||
if(entity instanceof TileEntityChest && isInTileEntity((TileEntityChest) entity, stack)) | ||
{ | ||
return pos; | ||
} | ||
} | ||
} | ||
return null; | ||
return getPositionOfChestWithItemStack(stack -> stack != null && is.isItemEqual(stack)); | ||
} | ||
|
||
/** | ||
|
@@ -368,7 +331,7 @@ public BlockPos getPositionOfChestWithTool(@NotNull final String tool,final int | |
final TileEntity entity = world.getTileEntity(pos); | ||
if (entity instanceof TileEntityChest | ||
&& ((minLevel != -1 && InventoryUtils.isPickaxeInProvider(entity, minLevel, requestingBuilding.getBuildingLevel())) | ||
|| InventoryUtils.isToolInProvider((TileEntityChest) entity, tool, requestingBuilding.getBuildingLevel()))) | ||
|| InventoryUtils.isToolInProvider(entity, tool, requestingBuilding.getBuildingLevel()))) | ||
{ | ||
return pos; | ||
} | ||
|
@@ -383,7 +346,7 @@ public BlockPos getPositionOfChestWithTool(@NotNull final String tool,final int | |
* @param requestingBuilding the building requesting it. | ||
* @return true if a stack of that type was found | ||
*/ | ||
public boolean isToolInHut(final String tool, @NotNull final AbstractBuilding requestingBuilding) | ||
private boolean isToolInHut(final String tool, @NotNull final AbstractBuilding requestingBuilding) | ||
{ | ||
@Nullable final AbstractBuilding building = getBuilding(); | ||
|
||
|
@@ -429,26 +392,6 @@ public boolean isToolInHut(final String tool, @NotNull final AbstractBuilding re | |
return false; | ||
} | ||
|
||
/** | ||
* Finds the first @see ItemStack the type of {@code is}. | ||
* It will be taken from the chest and placed in the workers inventory. | ||
* Make sure that the worker stands next the chest to not break immersion. | ||
* Also make sure to have inventory space for the stack. | ||
* @param entity the tileEntity chest or building. | ||
* @param is the itemStack. | ||
* @return true if found the stack. | ||
*/ | ||
public boolean isInTileEntity(TileEntityChest entity, ItemStack is) | ||
{ | ||
return is != null | ||
&& InventoryFunctions | ||
.matchFirstInProviderWithAction( | ||
entity, | ||
stack -> stack != null && is.isItemEqual(stack), | ||
InventoryFunctions::doNothing | ||
); | ||
} | ||
|
||
/** | ||
* Finds the first @see ItemStack the type of {@code is}. | ||
* It will be taken from the chest and placed in the workers inventory. | ||
|
@@ -458,14 +401,13 @@ public boolean isInTileEntity(TileEntityChest entity, ItemStack is) | |
* @param itemStackSelectionPredicate the itemStack predicate. | ||
* @return true if found the stack. | ||
*/ | ||
public boolean isInTileEntity(final TileEntityChest entity, @NotNull final Predicate<ItemStack> itemStackSelectionPredicate) | ||
private boolean isInTileEntity(final TileEntityChest entity, @NotNull final Predicate<ItemStack> itemStackSelectionPredicate) | ||
{ | ||
return InventoryFunctions | ||
.matchFirstInProviderWithAction( | ||
entity, | ||
itemStackSelectionPredicate, | ||
InventoryFunctions::doNothing | ||
); | ||
InventoryFunctions::doNothing); | ||
} | ||
|
||
@Override | ||
|
@@ -504,7 +446,6 @@ public void dumpInventoryIntoWareHouse(@NotNull final InventoryCitizen inventory | |
} | ||
InventoryUtils.transferItemStackIntoNextFreeSlotInProvider(new InvWrapper(inventoryCitizen), i, chest); | ||
} | ||
|
||
} | ||
|
||
/** | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This call to "contains()" may be a performance hot spot if the collection is large.