Merge remote-tracking branch 'LasmGratel/async-itemrepo' into AE2-Omnifactory
This commit is contained in:
@@ -39,7 +39,7 @@ import appeng.api.storage.IStorageChannel;
|
|||||||
* - For fluids: AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class).createList()
|
* - For fluids: AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class).createList()
|
||||||
* - Replace with the corresponding {@link IStorageChannel} type for non native channels
|
* - Replace with the corresponding {@link IStorageChannel} type for non native channels
|
||||||
*/
|
*/
|
||||||
public interface IItemList<T extends IAEStack<T>> extends IItemContainer<T>, Iterable<T>
|
public interface IItemList<T extends IAEStack<T>> extends IItemContainer<T>, Iterable<T>, Cloneable
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,4 +85,9 @@ public interface IItemList<T extends IAEStack<T>> extends IItemContainer<T>, Ite
|
|||||||
* resets stack sizes to 0.
|
* resets stack sizes to 0.
|
||||||
*/
|
*/
|
||||||
void resetStatus();
|
void resetStatus();
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* create a copy of this list.
|
||||||
|
*/
|
||||||
|
IItemList<T> clone();
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,19 +39,20 @@ import javax.annotation.Nonnull;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
public class ItemRepo {
|
public class ItemRepo {
|
||||||
|
|
||||||
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||||
private final ArrayList<IAEItemStack> view = new ArrayList<>();
|
private final List<IAEItemStack> view;
|
||||||
private final IScrollSource src;
|
private final IScrollSource src;
|
||||||
private final ISortSource sortSrc;
|
private final ISortSource sortSrc;
|
||||||
|
|
||||||
private int rowSize = 9;
|
private int rowSize = 9;
|
||||||
|
|
||||||
private String searchString = "";
|
private volatile String searchString = "";
|
||||||
private IPartitionList<IAEItemStack> myPartitionList;
|
private IPartitionList<IAEItemStack> myPartitionList;
|
||||||
private String innerSearch = "";
|
private String innerSearch = "";
|
||||||
private boolean hasPower;
|
private boolean hasPower;
|
||||||
@@ -59,6 +60,9 @@ public class ItemRepo {
|
|||||||
public ItemRepo(final IScrollSource src, final ISortSource sortSrc) {
|
public ItemRepo(final IScrollSource src, final ISortSource sortSrc) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.sortSrc = sortSrc;
|
this.sortSrc = sortSrc;
|
||||||
|
|
||||||
|
this.view = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
list.forEach(this.view::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAEItemStack getReferenceItem(int idx) {
|
public IAEItemStack getReferenceItem(int idx) {
|
||||||
@@ -95,111 +99,123 @@ public class ItemRepo {
|
|||||||
this.updateView();
|
this.updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Void> searchTask = null;
|
||||||
|
|
||||||
public void updateView() {
|
public void updateView() {
|
||||||
this.view.clear();
|
if (searchTask != null) {
|
||||||
|
searchTask.cancel(true);
|
||||||
this.view.ensureCapacity(this.list.size());
|
|
||||||
|
|
||||||
final Enum viewMode = this.sortSrc.getSortDisplay();
|
|
||||||
final Enum searchMode = AEConfig.instance().getConfigManager().getSetting(Settings.SEARCH_MODE);
|
|
||||||
final boolean needsZeroCopy = viewMode == ViewItems.CRAFTABLE;
|
|
||||||
|
|
||||||
if (searchMode == SearchBoxMode.JEI_AUTOSEARCH || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH || searchMode == SearchBoxMode.JEI_AUTOSEARCH_KEEP || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH_KEEP) {
|
|
||||||
this.updateJEI(this.searchString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean terminalSearchToolTips = AEConfig.instance().getConfigManager().getSetting(Settings.SEARCH_TOOLTIPS) != YesNo.NO;
|
// Since sortSrc is final, so we can safely call it inside lambda
|
||||||
|
searchTask = CompletableFuture.supplyAsync(() -> {
|
||||||
|
IItemList<IAEItemStack> list = this.list.clone();
|
||||||
|
List<IAEItemStack> view = new ArrayList<>(list.size());
|
||||||
|
Enum viewMode = this.sortSrc.getSortDisplay();
|
||||||
|
|
||||||
boolean searchMod = false;
|
boolean needsZeroCopy = viewMode == ViewItems.CRAFTABLE;
|
||||||
|
|
||||||
this.innerSearch = searchString.toLowerCase();
|
boolean terminalSearchToolTips = AEConfig.instance().getConfigManager().getSetting(Settings.SEARCH_TOOLTIPS) != YesNo.NO;
|
||||||
if (this.innerSearch.startsWith("@")) {
|
|
||||||
searchMod = true;
|
|
||||||
this.innerSearch = this.innerSearch.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pattern m = null;
|
boolean searchMod = false;
|
||||||
try {
|
|
||||||
m = Pattern.compile(this.innerSearch, Pattern.CASE_INSENSITIVE);
|
String innerSearch = searchString.toLowerCase();
|
||||||
} catch (final Throwable ignore) {
|
if (innerSearch.startsWith("@")) {
|
||||||
try {
|
searchMod = true;
|
||||||
m = Pattern.compile(Pattern.quote(this.innerSearch), Pattern.CASE_INSENSITIVE);
|
innerSearch = innerSearch.substring(1);
|
||||||
} catch (final Throwable __) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
boolean notDone = false;
|
Pattern m = null;
|
||||||
for (IAEItemStack is : this.list) {
|
try {
|
||||||
if (this.myPartitionList != null) {
|
m = Pattern.compile(innerSearch, Pattern.CASE_INSENSITIVE);
|
||||||
if (!this.myPartitionList.isListed(is)) {
|
} catch (final Throwable ignore) {
|
||||||
continue;
|
try {
|
||||||
|
m = Pattern.compile(Pattern.quote(innerSearch), Pattern.CASE_INSENSITIVE);
|
||||||
|
} catch (final Throwable __) {
|
||||||
|
return Collections.<IAEItemStack>emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewMode == ViewItems.CRAFTABLE && !is.isCraftable()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewMode == ViewItems.STORED && is.getStackSize() == 0) {
|
for (IAEItemStack is : list) {
|
||||||
continue;
|
if (this.myPartitionList != null) {
|
||||||
}
|
if (!this.myPartitionList.isListed(is)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String dspName = (searchMod ? Platform.getModId(is) : Platform.getItemDisplayName(is)).toLowerCase();
|
if (viewMode == ViewItems.CRAFTABLE && !is.isCraftable()) {
|
||||||
boolean foundMatchingItemStack = true;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (String term : innerSearch.split(" ")) {
|
if (viewMode == ViewItems.STORED && is.getStackSize() == 0) {
|
||||||
if (term.length() > 1 && (term.startsWith("-") || term.startsWith("!"))) {
|
continue;
|
||||||
term = term.substring(1);
|
}
|
||||||
if (dspName.contains(term)) {
|
|
||||||
|
final String dspName = (searchMod ? Platform.getModId(is) : Platform.getItemDisplayName(is)).toLowerCase();
|
||||||
|
boolean foundMatchingItemStack = true;
|
||||||
|
|
||||||
|
for (String term : innerSearch.split(" ")) {
|
||||||
|
if (term.length() > 1 && (term.startsWith("-") || term.startsWith("!"))) {
|
||||||
|
term = term.substring(1);
|
||||||
|
if (dspName.contains(term)) {
|
||||||
|
foundMatchingItemStack = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!dspName.contains(term)) {
|
||||||
foundMatchingItemStack = false;
|
foundMatchingItemStack = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (!dspName.contains(term)) {
|
|
||||||
foundMatchingItemStack = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (terminalSearchToolTips && !foundMatchingItemStack) {
|
if (terminalSearchToolTips && !foundMatchingItemStack) {
|
||||||
final List<String> tooltip = Platform.getTooltip(is);
|
final List<String> tooltip = Platform.getTooltip(is);
|
||||||
for (final String line : tooltip) {
|
for (final String line : tooltip) {
|
||||||
if (m.matcher(line).find()) {
|
if (m.matcher(line).find()) {
|
||||||
foundMatchingItemStack = true;
|
foundMatchingItemStack = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (foundMatchingItemStack) {
|
if (foundMatchingItemStack) {
|
||||||
if (needsZeroCopy) {
|
if (needsZeroCopy) {
|
||||||
is = is.copy();
|
is = is.copy();
|
||||||
is.setStackSize(0);
|
is.setStackSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.add(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.view.add(is);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final Enum SortBy = this.sortSrc.getSortBy();
|
final Enum SortBy = this.sortSrc.getSortBy();
|
||||||
final Enum SortDir = this.sortSrc.getSortDir();
|
final Enum SortDir = this.sortSrc.getSortDir();
|
||||||
|
|
||||||
ItemSorters.setDirection((appeng.api.config.SortDir) SortDir);
|
ItemSorters.setDirection((appeng.api.config.SortDir) SortDir);
|
||||||
ItemSorters.init();
|
ItemSorters.init();
|
||||||
|
|
||||||
if (SortBy == SortOrder.MOD) {
|
if (SortBy == SortOrder.MOD) {
|
||||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_MOD);
|
view.sort(ItemSorters.CONFIG_BASED_SORT_BY_MOD);
|
||||||
} else if (SortBy == SortOrder.AMOUNT) {
|
} else if (SortBy == SortOrder.AMOUNT) {
|
||||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_SIZE);
|
view.sort(ItemSorters.CONFIG_BASED_SORT_BY_SIZE);
|
||||||
} else if (SortBy == SortOrder.INVTWEAKS) {
|
} else if (SortBy == SortOrder.INVTWEAKS) {
|
||||||
if (InventoryBogoSortModule.isLoaded()) {
|
if (InventoryBogoSortModule.isLoaded()) {
|
||||||
Collections.sort(this.view, InventoryBogoSortModule.COMPARATOR);
|
Collections.sort(this.view, InventoryBogoSortModule.COMPARATOR);
|
||||||
|
} else {
|
||||||
|
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_INV_TWEAKS);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_INV_TWEAKS);
|
view.sort(ItemSorters.CONFIG_BASED_SORT_BY_NAME);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_NAME);
|
return view;
|
||||||
}
|
}).thenAcceptAsync(view -> {
|
||||||
|
this.view.clear();
|
||||||
|
this.view.addAll(view);
|
||||||
|
}).thenRunAsync(() -> {
|
||||||
|
this.searchTask = null; // Prevent redundant cancellation
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateJEI(String filter) {
|
private void updateJEI(String filter) {
|
||||||
@@ -211,6 +227,8 @@ public class ItemRepo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
searchTask.cancel(true);
|
||||||
|
searchTask = null;
|
||||||
this.list.resetStatus();
|
this.list.resetStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,5 +254,16 @@ public class ItemRepo {
|
|||||||
|
|
||||||
public void setSearchString(@Nonnull final String searchString) {
|
public void setSearchString(@Nonnull final String searchString) {
|
||||||
this.searchString = searchString;
|
this.searchString = searchString;
|
||||||
|
|
||||||
|
if (searchTask != null) {
|
||||||
|
searchTask.cancel(true);
|
||||||
|
searchTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passive JEI auto search
|
||||||
|
final Enum<?> searchMode = AEConfig.instance().getConfigManager().getSetting(Settings.SEARCH_MODE);
|
||||||
|
if (searchMode == SearchBoxMode.JEI_AUTOSEARCH || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH || searchMode == SearchBoxMode.JEI_AUTOSEARCH_KEEP || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH_KEEP) {
|
||||||
|
this.updateJEI(this.searchString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,13 @@ public final class FluidList implements IItemList<IAEFluidStack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidList clone() {
|
||||||
|
FluidList list = new FluidList();
|
||||||
|
list.records.putAll(records);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
private IAEFluidStack getFluidRecord(final IAEFluidStack fluid) {
|
private IAEFluidStack getFluidRecord(final IAEFluidStack fluid) {
|
||||||
return this.records.get(fluid);
|
return this.records.get(fluid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,4 +94,9 @@ public class ItemListIgnoreCrafting<T extends IAEStack<T>> implements IItemList<
|
|||||||
public void resetStatus() {
|
public void resetStatus() {
|
||||||
this.target.resetStatus();
|
this.target.resetStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemListIgnoreCrafting<T> clone() {
|
||||||
|
return new ItemListIgnoreCrafting<>(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,6 +140,14 @@ public final class ItemList implements IItemList<IAEItemStack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemList clone() {
|
||||||
|
ItemList list = new ItemList();
|
||||||
|
list.records.putAll(records);
|
||||||
|
list.version.set(version.get());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
private ItemVariantList getOrCreateRecord(Item item) {
|
private ItemVariantList getOrCreateRecord(Item item) {
|
||||||
return this.records.computeIfAbsent(item, this::makeRecordMap);
|
return this.records.computeIfAbsent(item, this::makeRecordMap);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user