From 24db9e1cc0456d233bbcc4a94fbe9ee61a560c0f Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Thu, 4 Feb 2021 18:52:38 +0800 Subject: [PATCH] Port optimizations --- .../mixin/forge/PacketDistributorMixin.java | 4 + arclight-forge-1.16/build.gradle | 6 +- .../arclight/impl/ArclightConnector_1_16.java | 8 +- .../optimization/OptimizedIndirectMerger.java | 127 ++++++++++++++++++ .../ClassInheritanceMultiMapMixin.java | 51 +++++++ .../general/VoxelShapesMixin.java | 19 +++ .../stream/GoalSelectorMixin.java | 111 +++++++++++++++ .../stream/ITaskQueue_PriorityMixin.java | 30 +++++ ...ixins.arclight.impl.optimization.1_16.json | 10 ++ ...rclight.impl.optimization.stream.1_16.json | 10 ++ 10 files changed, 371 insertions(+), 5 deletions(-) create mode 100644 arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/common/optimization/OptimizedIndirectMerger.java create mode 100644 arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/ClassInheritanceMultiMapMixin.java create mode 100644 arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/VoxelShapesMixin.java create mode 100644 arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/GoalSelectorMixin.java create mode 100644 arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/ITaskQueue_PriorityMixin.java create mode 100644 arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json create mode 100644 arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.stream.1_16.json diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/PacketDistributorMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/PacketDistributorMixin.java index caab8ef0..74122113 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/PacketDistributorMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/PacketDistributorMixin.java @@ -12,6 +12,10 @@ import java.util.function.Supplier; @Mixin(PacketDistributor.class) public class PacketDistributorMixin { + /** + * @author IzzelAliz + * @reason + */ @Overwrite(remap = false) private Consumer> playerConsumer(Supplier entityPlayerMPSupplier) { return p -> { diff --git a/arclight-forge-1.16/build.gradle b/arclight-forge-1.16/build.gradle index 7d3422da..d9ad9ae3 100644 --- a/arclight-forge-1.16/build.gradle +++ b/arclight-forge-1.16/build.gradle @@ -80,7 +80,9 @@ dependencies { } embed 'net.md-5:bungeecord-chat:1.16-R0.4@jar' embed "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar" - embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar' + embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar' + annotationProcessor 'org.spongepowered:mixin:0.8.2:processor' + annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0' } def getGitHash = { -> @@ -121,7 +123,7 @@ remapSpigotJar { } mixin { - // add sourceSets.main, 'mixins.arclight.impl.refmap.1_15.json' + add sourceSets.main, 'mixins.arclight.impl.refmap.1_16.json' } compileJava { diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java index 10d632c9..5729e105 100644 --- a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java @@ -1,6 +1,8 @@ package io.izzel.arclight.impl; import io.izzel.arclight.common.mod.ArclightConnector; +import io.izzel.arclight.i18n.ArclightConfig; +import org.spongepowered.asm.mixin.Mixins; @SuppressWarnings("unused") public class ArclightConnector_1_16 extends ArclightConnector { @@ -8,10 +10,10 @@ public class ArclightConnector_1_16 extends ArclightConnector { @Override public void connect() { super.connect(); - /* + Mixins.addConfiguration("mixins.arclight.impl.optimization.1_16.json"); if (ArclightConfig.spec().getOptimization().isRemoveStream()) { - Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_15.json"); + Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_16.json"); } - LOGGER.info("mixin-load.optimization");*/ + LOGGER.info("mixin-load.optimization"); } } diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/common/optimization/OptimizedIndirectMerger.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/common/optimization/OptimizedIndirectMerger.java new file mode 100644 index 00000000..504b7551 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/common/optimization/OptimizedIndirectMerger.java @@ -0,0 +1,127 @@ +package io.izzel.arclight.impl.common.optimization; + +import it.unimi.dsi.fastutil.doubles.DoubleArrayList; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.util.math.shapes.IDoubleListMerger; +import org.jetbrains.annotations.NotNull; + +/** + * @author jellysquid3 (LGPLv3) + */ +public class OptimizedIndirectMerger implements IDoubleListMerger { + + private final double[] merged; + private final int[] indicesFirst; + private final int[] indicesSecond; + + private final DoubleArrayList pairs; + + public OptimizedIndirectMerger(DoubleList aPoints, DoubleList bPoints, boolean flag1, boolean flag2) { + double[] araw; + + if (aPoints instanceof DoubleArrayList) { + araw = ((DoubleArrayList) aPoints).elements(); + } else { + araw = new double[aPoints.size()]; + + for (int i = 0; i < araw.length; i++) { + araw[i] = aPoints.getDouble(i); + } + } + + double[] braw; + + if (bPoints instanceof DoubleArrayList) { + braw = ((DoubleArrayList) bPoints).elements(); + } else { + braw = new double[bPoints.size()]; + + for (int i = 0; i < braw.length; i++) { + braw[i] = bPoints.getDouble(i); + } + } + + int size = araw.length + braw.length; + + this.merged = new double[size]; + this.indicesFirst = new int[size]; + this.indicesSecond = new int[size]; + + this.pairs = DoubleArrayList.wrap(this.merged); + + this.merge(araw, braw, araw.length, braw.length, flag1, flag2); + } + + private void merge(double[] aPoints, double[] bPoints, int aSize, int bSize, boolean flag1, boolean flag2) { + int aIdx = 0; + int bIdx = 0; + + double prev = 0.0D; + + int a1 = 0, a2 = 0; + + while (true) { + boolean aWithinBounds = aIdx < aSize; + boolean bWithinBounds = bIdx < bSize; + + if (!aWithinBounds && !bWithinBounds) { + break; + } + + boolean flip = aWithinBounds && (!bWithinBounds || aPoints[aIdx] < bPoints[bIdx] + 1.0E-7D); + + double value; + + if (flip) { + value = aPoints[aIdx++]; + } else { + value = bPoints[bIdx++]; + } + + if ((aIdx == 0 || !aWithinBounds) && !flip && !flag2) { + continue; + } + + if ((bIdx == 0 || !bWithinBounds) && flip && !flag1) { + continue; + } + + if (a2 == 0 || prev < value - 1.0E-7D) { + this.indicesFirst[a1] = aIdx - 1; + this.indicesSecond[a1] = bIdx - 1; + this.merged[a2] = value; + + a1++; + a2++; + prev = value; + } else if (a2 > 0) { + this.indicesFirst[a1 - 1] = aIdx - 1; + this.indicesSecond[a1 - 1] = bIdx - 1; + } + } + + if (a2 == 0) { + this.merged[a2++] = Math.min(aPoints[aSize - 1], bPoints[bSize - 1]); + } + + this.pairs.size(a2); + } + + @Override + public @NotNull DoubleList func_212435_a() { + return this.pairs; + } + + @Override + public boolean forMergedIndexes(@NotNull IConsumer consumer) { + int l = this.pairs.size() - 1; + + for (int i = 0; i < l; i++) { + if (!consumer.merge(this.indicesFirst[i], this.indicesSecond[i], i)) { + return false; + } + } + + return true; + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/ClassInheritanceMultiMapMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/ClassInheritanceMultiMapMixin.java new file mode 100644 index 00000000..27d92fda --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/ClassInheritanceMultiMapMixin.java @@ -0,0 +1,51 @@ +package io.izzel.arclight.impl.mixin.optimization.general; + +import net.minecraft.util.ClassInheritanceMultiMap; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Mixin(ClassInheritanceMultiMap.class) +public class ClassInheritanceMultiMapMixin { + + // @formatter:off + @Shadow @Final private Class baseClass; + @Shadow @Final private Map, List> map; + @Shadow @Final private List values; + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public Collection getByClass(Class p_219790_1_) { + Collection collection = this.map.get(p_219790_1_); + if (collection == null) { + collection = this.createList(p_219790_1_); + } + return (Collection) Collections.unmodifiableCollection(collection); + } + + private Collection createList(Class p_219790_1_) { + if (!this.baseClass.isAssignableFrom(p_219790_1_)) { + throw new IllegalArgumentException("Don't know how to search for " + p_219790_1_); + } else { + List list = new ArrayList<>(); + for (T value : this.values) { + if (p_219790_1_.isInstance(value)) { + list.add(value); + } + } + this.map.put(p_219790_1_, list); + return list; + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/VoxelShapesMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/VoxelShapesMixin.java new file mode 100644 index 00000000..52b38702 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/VoxelShapesMixin.java @@ -0,0 +1,19 @@ +package io.izzel.arclight.impl.mixin.optimization.general; + +import io.izzel.arclight.impl.common.optimization.OptimizedIndirectMerger; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.util.math.shapes.IDoubleListMerger; +import net.minecraft.util.math.shapes.VoxelShapes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(VoxelShapes.class) +public class VoxelShapesMixin { + + @Inject(method = "makeListMerger", at = @At(value = "NEW", target = "net/minecraft/util/math/shapes/IndirectMerger", shift = At.Shift.BEFORE), cancellable = true) + private static void arclight$optimizedMerger(int p_199410_0_, DoubleList list1, DoubleList list2, boolean p_199410_3_, boolean p_199410_4_, CallbackInfoReturnable cir) { + cir.setReturnValue(new OptimizedIndirectMerger(list1, list2, p_199410_3_, p_199410_4_)); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/GoalSelectorMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/GoalSelectorMixin.java new file mode 100644 index 00000000..59c3da7f --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/GoalSelectorMixin.java @@ -0,0 +1,111 @@ +package io.izzel.arclight.impl.mixin.optimization.stream; + +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.entity.ai.goal.GoalSelector; +import net.minecraft.entity.ai.goal.PrioritizedGoal; +import net.minecraft.profiler.IProfiler; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Stream; + +@Mixin(GoalSelector.class) +public abstract class GoalSelectorMixin { + + // @formatter:off + @Shadow @Final private Set goals; + @Shadow @Final private Supplier profiler; + @Shadow public abstract Stream getRunningGoals(); + @Shadow @Final private EnumSet disabledFlags; + @Shadow @Final private Map flagGoals; + @Shadow @Final private static PrioritizedGoal DUMMY; + // @formatter:on + + /** + * @author IzzelAliz + * @reason optimization + */ + @Overwrite + public void removeGoal(Goal task) { + for (Iterator iterator = this.goals.iterator(); iterator.hasNext(); ) { + PrioritizedGoal goal = iterator.next(); + if (goal.getGoal() == task) { + if (goal.isRunning()) { + goal.resetTask(); + } + iterator.remove(); + } + } + } + + /** + * @author IzzelAliz + * @reason optimization + */ + @Overwrite + public void tick() { + IProfiler iprofiler = this.profiler.get(); + iprofiler.startSection("goalCleanup"); + for (PrioritizedGoal prioritizedGoal : this.goals) { + if (prioritizedGoal.isRunning()) { + EnumSet flags = this.disabledFlags; + boolean b = false; + for (Goal.Flag flag : prioritizedGoal.getMutexFlags()) { + if (flags.contains(flag)) { + b = true; + break; + } + } + if (!prioritizedGoal.isRunning() || b || !prioritizedGoal.shouldContinueExecuting()) { + prioritizedGoal.resetTask(); + } + } + } + for (Iterator> iterator = this.flagGoals.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry entry = iterator.next(); + PrioritizedGoal p_220885_2_ = entry.getValue(); + if (!p_220885_2_.isRunning()) { + iterator.remove(); + } + } + iprofiler.endSection(); + iprofiler.startSection("goalUpdate"); + for (PrioritizedGoal goal : this.goals) { + if (!goal.isRunning()) { + EnumSet flags = this.disabledFlags; + boolean b = true; + for (Goal.Flag flag1 : goal.getMutexFlags()) { + if (flags.contains(flag1) || !this.flagGoals.getOrDefault(flag1, DUMMY).isPreemptedBy(goal)) { + b = false; + break; + } + } + if (b) { + if (goal.shouldExecute()) { + for (Goal.Flag flag : goal.getMutexFlags()) { + PrioritizedGoal prioritizedgoal = this.flagGoals.getOrDefault(flag, DUMMY); + prioritizedgoal.resetTask(); + this.flagGoals.put(flag, goal); + } + goal.startExecuting(); + } + } + } + } + iprofiler.endSection(); + iprofiler.startSection("goalTick"); + for (PrioritizedGoal goal : this.goals) { + if (goal.isRunning()) { + goal.tick(); + } + } + iprofiler.endSection(); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/ITaskQueue_PriorityMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/ITaskQueue_PriorityMixin.java new file mode 100644 index 00000000..c86f5927 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/stream/ITaskQueue_PriorityMixin.java @@ -0,0 +1,30 @@ +package io.izzel.arclight.impl.mixin.optimization.stream; + +import net.minecraft.util.concurrent.ITaskQueue; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; +import java.util.Queue; + +@Mixin(ITaskQueue.Priority.class) +public class ITaskQueue_PriorityMixin { + + @Shadow @Final private List> queues; + + /** + * @author IzzelAliz + * @reason optimization + */ + @Overwrite + public boolean isEmpty() { + for (Queue queue : this.queues) { + if (!queue.isEmpty()) { + return false; + } + } + return true; + } +} diff --git a/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json new file mode 100644 index 00000000..ec081ebc --- /dev/null +++ b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json @@ -0,0 +1,10 @@ +{ + "minVersion": "0.8", + "package": "io.izzel.arclight.impl.mixin.optimization.general", + "target": "@env(DEFAULT)", + "refmap": "mixins.arclight.impl.refmap.1_16.json", + "mixins": [ + "ClassInheritanceMultiMapMixin", + "VoxelShapesMixin" + ] +} \ No newline at end of file diff --git a/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.stream.1_16.json b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.stream.1_16.json new file mode 100644 index 00000000..8234766a --- /dev/null +++ b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.stream.1_16.json @@ -0,0 +1,10 @@ +{ + "minVersion": "0.8", + "package": "io.izzel.arclight.impl.mixin.optimization.stream", + "target": "@env(DEFAULT)", + "refmap": "mixins.arclight.impl.refmap.1_16.json", + "mixins": [ + "GoalSelectorMixin", + "ITaskQueue_PriorityMixin" + ] +} \ No newline at end of file