diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-06-20 21:08:02 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-29 21:02:40 +0800 |
| commit | 342e0c0cbd98e0978d08b86c8c3c0fd2ba7d19bf (patch) | |
| tree | cf72925388be51be6cf1b12f640e7db9ae94fe39 /runtime/src/main/java | |
| parent | 35841904482b47e315643ca59c3ca42a5187172e (diff) | |
| download | RoughlyEnoughItems-342e0c0cbd98e0978d08b86c8c3c0fd2ba7d19bf.tar.gz RoughlyEnoughItems-342e0c0cbd98e0978d08b86c8c3c0fd2ba7d19bf.tar.bz2 RoughlyEnoughItems-342e0c0cbd98e0978d08b86c8c3c0fd2ba7d19bf.zip | |
Refactor EntryRegistryImpl
Diffstat (limited to 'runtime/src/main/java')
5 files changed, 356 insertions, 88 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java index 8f753c0b2..892b0d68c 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java @@ -23,9 +23,10 @@ package me.shedaniel.rei.impl.common.entry.type; -import com.google.common.base.MoreObjects; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongList; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; import me.shedaniel.rei.RoughlyEnoughItemsCore; @@ -38,8 +39,6 @@ import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext; import me.shedaniel.rei.api.common.entry.type.EntryDefinition; -import me.shedaniel.rei.api.common.entry.type.EntryType; -import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.util.CollectionUtils; @@ -55,7 +54,6 @@ import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.core.NonNullList; -import net.minecraft.core.Registry; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -74,10 +72,8 @@ import java.util.stream.Stream; public class EntryRegistryImpl implements EntryRegistry { public List<Runnable> refilterListener = Lists.newCopyOnWriteArrayList(); private List<EntryStack<?>> preFilteredList = Lists.newCopyOnWriteArrayList(); - private List<EntryStack<?>> entries = Lists.newCopyOnWriteArrayList(); + private EntryRegistryList registryList; private LongSet entriesHash = new LongOpenHashSet(); - @Nullable - private List<HashedEntryStackWrapper> reloadingRegistry; private boolean reloading; @Override @@ -93,9 +89,8 @@ public class EntryRegistryImpl implements EntryRegistry { @Override public void startReload() { refilterListener.clear(); - entries = Lists.newCopyOnWriteArrayList(); + registryList = new ReloadingEntryRegistryList(); entriesHash = new LongOpenHashSet(); - reloadingRegistry = Lists.newArrayListWithCapacity(Registry.ITEM.keySet().size() + 100); preFilteredList = Lists.newCopyOnWriteArrayList(); reloading = true; } @@ -104,20 +99,22 @@ public class EntryRegistryImpl implements EntryRegistry { public void endReload() { reloading = false; preFilteredList = Lists.newCopyOnWriteArrayList(); - entries = Lists.newCopyOnWriteArrayList(CollectionUtils.filterAndMap(reloadingRegistry, ((Predicate<HashedEntryStackWrapper>) HashedEntryStackWrapper::isEmpty).negate(), HashedEntryStackWrapper::unwrap)); - reloadingRegistry = null; + if (!(registryList instanceof ReloadingEntryRegistryList)) { + throw new IllegalStateException("Expected ReloadingEntryRegistryList, got " + registryList.getClass().getName()); + } + registryList = new NormalEntryRegistryList(registryList.stream().filter(((Predicate<EntryStack<?>>) EntryStack::isEmpty).negate())); refilter(); REIRuntime.getInstance().getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); } @Override public int size() { - return reloading ? reloadingRegistry.size() : entries.size(); + return registryList.size(); } @Override public Stream<EntryStack<?>> getEntryStacks() { - return reloading ? reloadingRegistry.stream().map(HashedEntryStackWrapper::unwrap) : entries.stream(); + return registryList.stream(); } @Override @@ -137,6 +134,7 @@ public class EntryRegistryImpl implements EntryRegistry { Stopwatch stopwatch = Stopwatch.createStarted(); + List<EntryStack<?>> entries = ((NormalEntryRegistryList) registryList).getList(); FilteringContextImpl context = new FilteringContextImpl(entries); FilteringCacheImpl cache = new FilteringCacheImpl(); List<FilteringRule<?>> rules = ((ConfigObjectImpl) ConfigObject.getInstance()).getFilteringRules(); @@ -199,45 +197,6 @@ public class EntryRegistryImpl implements EntryRegistry { return list; } - @Override - public void addEntryAfter(@Nullable EntryStack<?> afterEntry, EntryStack<?> stack) { - if (reloading) { - int index = afterEntry != null ? reloadingRegistry.lastIndexOf(new HashedEntryStackWrapper(afterEntry)) : -1; - HashedEntryStackWrapper wrapper = new HashedEntryStackWrapper(stack); - if (this.entriesHash.add(wrapper.hashExact())) { - if (index >= 0) { - reloadingRegistry.add(index, wrapper); - } else reloadingRegistry.add(wrapper); - } - } else if (this.entriesHash.add(EntryStacks.hashExact(stack))) { - if (afterEntry != null) { - int index = entries.lastIndexOf(afterEntry); - entries.add(index, stack); - } else entries.add(stack); - preFilteredList.addAll(refilterNew(true, Collections.singletonList(stack))); - queueSearchUpdate(); - } - } - - @Override - public void addEntriesAfter(@Nullable EntryStack<?> afterEntry, Collection<? extends EntryStack<?>> stacks) { - if (reloading) { - int index = afterEntry != null ? reloadingRegistry.lastIndexOf(new HashedEntryStackWrapper(afterEntry)) : -1; - List<HashedEntryStackWrapper> filtered = CollectionUtils.mapAndFilter(stacks, wrapper -> entriesHash.add(wrapper.hashExact()), HashedEntryStackWrapper::new); - if (index >= 0) { - reloadingRegistry.addAll(index, filtered); - } else reloadingRegistry.addAll(filtered); - } else { - List<EntryStack<?>> filtered = CollectionUtils.filterToList((Collection<EntryStack<?>>) stacks, stack -> entriesHash.add(EntryStacks.hashExact(stack))); - if (afterEntry != null) { - int index = entries.lastIndexOf(afterEntry); - entries.addAll(index, filtered); - } else entries.addAll(filtered); - preFilteredList.addAll(refilterNew(true, filtered)); - queueSearchUpdate(); - } - } - private void queueSearchUpdate() { if (REIRuntimeImpl.getSearchField() != null) { ScreenOverlayImpl.getInstance().queueReloadSearch(); @@ -283,41 +242,78 @@ public class EntryRegistryImpl implements EntryRegistry { } @Override - public boolean removeEntry(EntryStack<?> stack) { - if (reloading) { - HashedEntryStackWrapper wrapper = new HashedEntryStackWrapper(stack); - reloadingRegistry.remove(wrapper); - return entriesHash.remove(wrapper.hashExact()); + public void addEntryAfter(@Nullable EntryStack<?> afterEntry, EntryStack<?> stack) { + long hashExact = EntryStacks.hashExact(stack); + if (this.entriesHash.add(hashExact)) { + if (afterEntry != null) { + int index = registryList.lastIndexOf(afterEntry); + registryList.add(index, stack, hashExact); + } else registryList.add(stack, hashExact); + + if (!reloading) { + preFilteredList.addAll(refilterNew(true, Collections.singletonList(stack))); + queueSearchUpdate(); + } + } + } + + @Override + public void addEntriesAfter(@Nullable EntryStack<?> afterEntry, Collection<? extends EntryStack<?>> stacks) { + List<EntryStack<?>> filtered; + LongList hashes = registryList.needsHash() ? new LongArrayList(stacks.size()) : null; + + if (registryList.needsHash()) { + filtered = new ArrayList<>(stacks.size()); + for (EntryStack<?> stack : stacks) { + long hashExact = EntryStacks.hashExact(stack); + if (entriesHash.add(hashExact)) { + filtered.add(stack); + hashes.add(hashExact); + } + } } else { + filtered = CollectionUtils.filterToList((List<EntryStack<?>>) stacks, entry -> entriesHash.add(EntryStacks.hashExact(entry))); + } + + if (afterEntry != null) { + int index = registryList.lastIndexOf(afterEntry); + registryList.addAll(index, filtered, hashes); + } else registryList.addAll(filtered, hashes); + + if (!reloading) { + preFilteredList.addAll(refilterNew(true, filtered)); + queueSearchUpdate(); + } + } + + @Override + public boolean removeEntry(EntryStack<?> stack) { + long hashExact = EntryStacks.hashExact(stack); + registryList.remove(stack, hashExact); + boolean removed = entriesHash.remove(hashExact); + + if (removed && !reloading) { preFilteredList.remove(stack); - entries.remove(stack); - return entriesHash.remove(EntryStacks.hashExact(stack)); + queueSearchUpdate(); } + + return removed; } @Override public boolean removeEntryIf(Predicate<? extends EntryStack<?>> predicate) { - if (reloading) { - return reloadingRegistry.removeIf(wrapper -> { - if (((Predicate<EntryStack<?>>) predicate).test(wrapper.unwrap())) { - entriesHash.remove(wrapper.hashExact()); - return true; - } - - return false; - }); - } else { - Predicate<EntryStack<?>> entryStackPredicate = stack -> { - if (((Predicate<EntryStack<?>>) predicate).test(stack)) { - entriesHash.remove(EntryStacks.hashExact(stack)); - return true; - } - - return false; - }; - preFilteredList.removeIf(entryStackPredicate); - return entries.removeIf(entryStackPredicate); + if (!reloading) { + preFilteredList.removeIf((Predicate<? super EntryStack<?>>) predicate); } + + return registryList.removeIf(stack -> { + if (((Predicate<EntryStack<?>>) predicate).test(stack)) { + entriesHash.remove(EntryStacks.hashExact(stack)); + return true; + } + + return false; + }); } @Override @@ -331,12 +327,10 @@ public class EntryRegistryImpl implements EntryRegistry { return false; }; - if (reloading) { - return reloadingRegistry.removeIf(wrapper -> entryStackPredicate.test(wrapper.hashExact())); - } else { - preFilteredList.removeIf(stack -> entryStackPredicate.test(EntryStacks.hashExact(stack))); - return entries.removeIf(stack -> entryStackPredicate.test(EntryStacks.hashExact(stack))); + if (!reloading) { + preFilteredList.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack))); } + return registryList.removeExactIf(entryStackPredicate); } @Override @@ -350,11 +344,9 @@ public class EntryRegistryImpl implements EntryRegistry { return false; }; - if (reloading) { - return reloadingRegistry.removeIf(wrapper -> entryStackPredicate.test(wrapper.unwrap())); - } else { + if (!reloading) { preFilteredList.removeIf(entryStackPredicate); - return entries.removeIf(entryStackPredicate); } + return registryList.removeIf(entryStackPredicate); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java new file mode 100644 index 000000000..d60f10cb5 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java @@ -0,0 +1,58 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.common.entry.type; + +import it.unimi.dsi.fastutil.longs.LongList; +import me.shedaniel.rei.api.common.entry.EntryStack; + +import java.util.List; +import java.util.function.LongPredicate; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public interface EntryRegistryList { + int size(); + + Stream<EntryStack<?>> stream(); + + int indexOf(EntryStack<?> stack); + + int lastIndexOf(EntryStack<?> stack); + + void add(EntryStack<?> stack, long hashExact); + + void add(int index, EntryStack<?> stack, long hashExact); + + void addAll(List<EntryStack<?>> stacks, LongList hashes); + + void addAll(int index, List<EntryStack<?>> stacks, LongList hashes); + + void remove(EntryStack<?> stack, long hashExact); + + boolean removeIf(Predicate<? extends EntryStack<?>> predicate); + + boolean removeExactIf(LongPredicate predicate); + + boolean needsHash(); +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/NormalEntryRegistryList.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/NormalEntryRegistryList.java new file mode 100644 index 000000000..fc3046002 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/NormalEntryRegistryList.java @@ -0,0 +1,110 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.common.entry.type; + +import it.unimi.dsi.fastutil.longs.LongList; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryStacks; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.LongPredicate; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class NormalEntryRegistryList implements EntryRegistryList { + private List<EntryStack<?>> list = new ArrayList<>(); + + public NormalEntryRegistryList() { + } + + public NormalEntryRegistryList(Stream<EntryStack<?>> list) { + list.collect(Collectors.toCollection(() -> this.list)); + } + + @Override + public int size() { + return list.size(); + } + + @Override + public Stream<EntryStack<?>> stream() { + return list.stream(); + } + + @Override + public int indexOf(EntryStack<?> stack) { + return list.indexOf(stack); + } + + @Override + public int lastIndexOf(EntryStack<?> stack) { + return list.lastIndexOf(stack); + } + + @Override + public void add(EntryStack<?> stack, long hashExact) { + list.add(stack); + } + + @Override + public void add(int index, EntryStack<?> stack, long hashExact) { + list.add(index, stack); + } + + @Override + public void addAll(List<EntryStack<?>> stacks, LongList hashes) { + list.addAll(stacks); + } + + @Override + public void addAll(int index, List<EntryStack<?>> stacks, LongList hashes) { + list.addAll(index, stacks); + } + + @Override + public void remove(EntryStack<?> stack, long hashExact) { + list.remove(stack); + } + + @Override + public boolean removeIf(Predicate<? extends EntryStack<?>> predicate) { + return list.removeIf((Predicate<? super EntryStack<?>>) predicate); + } + + @Override + public boolean removeExactIf(LongPredicate predicate) { + return list.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack))); + } + + @Override + public boolean needsHash() { + return false; + } + + public List<EntryStack<?>> getList() { + return list; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/ReloadingEntryRegistryList.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/ReloadingEntryRegistryList.java new file mode 100644 index 000000000..45578585e --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/ReloadingEntryRegistryList.java @@ -0,0 +1,102 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.common.entry.type; + +import it.unimi.dsi.fastutil.longs.LongList; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; +import net.minecraft.core.Registry; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.LongPredicate; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public class ReloadingEntryRegistryList implements EntryRegistryList { + private List<HashedEntryStackWrapper> list = new ArrayList<>(Registry.ITEM.keySet().size() + 100); + + @Override + public int size() { + return list.size(); + } + + @Override + public Stream<EntryStack<?>> stream() { + return list.stream().map(HashedEntryStackWrapper::unwrap); + } + + @Override + public int indexOf(EntryStack<?> stack) { + return list.indexOf(new HashedEntryStackWrapper(stack)); + } + + @Override + public int lastIndexOf(EntryStack<?> stack) { + return list.lastIndexOf(new HashedEntryStackWrapper(stack)); + } + + @Override + public void add(EntryStack<?> stack, long hashExact) { + list.add(new HashedEntryStackWrapper(stack, hashExact)); + } + + @Override + public void add(int index, EntryStack<?> stack, long hashExact) { + list.add(index, new HashedEntryStackWrapper(stack, hashExact)); + } + + @Override + public void addAll(List<EntryStack<?>> stacks, LongList hashes) { + List<HashedEntryStackWrapper> wrappers = CollectionUtils.mapIndexed(stacks, (i, stack) -> new HashedEntryStackWrapper(stack, hashes.getLong(i))); + list.addAll(wrappers); + } + + @Override + public void addAll(int index, List<EntryStack<?>> stacks, LongList hashes) { + List<HashedEntryStackWrapper> wrappers = CollectionUtils.mapIndexed(stacks, (i, stack) -> new HashedEntryStackWrapper(stack, hashes.getLong(i))); + list.addAll(index, wrappers); + } + + @Override + public void remove(EntryStack<?> stack, long hashExact) { + list.remove(new HashedEntryStackWrapper(stack, hashExact)); + } + + @Override + public boolean removeIf(Predicate<? extends EntryStack<?>> predicate) { + return list.removeIf(wrapper -> ((Predicate<EntryStack<?>>) predicate).test(wrapper.unwrap())); + } + + @Override + public boolean removeExactIf(LongPredicate predicate) { + return list.removeIf(wrapper -> predicate.test(wrapper.hashExact())); + } + + @Override + public boolean needsHash() { + return true; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java index c11aad0ef..401f9a174 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java @@ -44,6 +44,12 @@ public class HashedEntryStackWrapper { this.hashInt = Long.hashCode(this.hash); } + public HashedEntryStackWrapper(EntryStack<?> stack, long hash) { + this.stack = Objects.requireNonNull(stack); + this.hash = hash; + this.hashInt = Long.hashCode(this.hash); + } + @Override public boolean equals(Object o) { return o instanceof HashedEntryStackWrapper && hash == ((HashedEntryStackWrapper) o).hash; |
