Skip to content

Commit bb405af

Browse files
authored
Merge pull request #5 from Harveykang/1.9/fixes
修复原版 ParticleGroup 计数bug、修复 clearParticles 时的内存泄漏。
2 parents 1c35a77 + 7b2b54d commit bb405af

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/main/java/cn/coostack/cooparticlesapi/mixin/ParticleManagerMixin.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
import net.minecraft.client.particle.ParticleManager;
88
import net.minecraft.client.particle.ParticleTextureSheet;
99
import org.spongepowered.asm.mixin.Final;
10+
import net.minecraft.particle.ParticleGroup;
1011
import org.spongepowered.asm.mixin.Mixin;
1112
import org.spongepowered.asm.mixin.Shadow;
13+
import org.spongepowered.asm.mixin.Unique;
1214
import org.spongepowered.asm.mixin.injection.At;
15+
import org.spongepowered.asm.mixin.injection.Inject;
1316
import org.spongepowered.asm.mixin.injection.Redirect;
17+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1418

1519
import java.util.Map;
1620
import java.util.Queue;
@@ -25,6 +29,9 @@ public abstract class ParticleManagerMixin {
2529
@Shadow
2630
private Queue<Particle> newParticles;
2731

32+
@Shadow
33+
protected abstract void addTo(ParticleGroup group, int count);
34+
2835
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Ljava/util/Queue;poll()Ljava/lang/Object;"))
2936
public Object changeMaxParticles(Queue<Object> queue) {
3037
// 不需要判断 EnabledParticleCountInject 了,已在注入时判断,关这个一般都是因为会注入失败,所以不用担心
@@ -34,13 +41,29 @@ public Object changeMaxParticles(Queue<Object> queue) {
3441
Queue<Particle> queue1 = particles.computeIfAbsent(particle.getType(),
3542
sheet -> EvictingQueue.create(limit));
3643
// limit 在程序生命周期内不会改变,这里可以直接判断
37-
if (queue1.size() < limit) {
38-
queue1.add(particle);
39-
} else {
44+
if (queue1.size() == limit) {
4045
// 这样驱逐队列就没用了但是可以避免内存泄漏
41-
particle.markDead();
46+
Particle poll = queue1.poll();
47+
if (poll != null) onEvict(poll);
4248
}
49+
queue1.add(particle);
4350
}
4451
return null;
4552
}
53+
54+
@Inject(method = "clearParticles", at = @At("HEAD"))
55+
public void clearParticles(CallbackInfo ci) {
56+
particles.values().forEach(q -> q.forEach(this::onEvict));
57+
newParticles.forEach(this::onEvict);
58+
}
59+
60+
@Unique
61+
private void onEvict(Particle p) {
62+
// 这是原版 bug,但本模组会放大这个问题所以有必要修复一下
63+
// 判断 isAlive 以保证幂等性(其他模组可能注入类似方法)
64+
if (p.isAlive()) {
65+
p.markDead();
66+
p.getGroup().ifPresent(group -> addTo(group, -1));
67+
}
68+
}
4669
}

src/main/kotlin/cn/coostack/cooparticlesapi/config/APIConfig.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package cn.coostack.cooparticlesapi.config
22

3+
import kotlin.math.max
4+
35
class APIConfig {
46
/**
57
* 是否启用ParticleManagerMixin 对粒子数量上限进行修改
@@ -12,4 +14,5 @@ class APIConfig {
1214
* 原版上限为65536
1315
*/
1416
var particleCountLimit = 65536
17+
get() = max(field, 1)
1518
}

0 commit comments

Comments
 (0)