Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ public abstract class ParticleManagerMixin {

@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Ljava/util/Queue;poll()Ljava/lang/Object;"))
public Object changeMaxParticles(Queue<Object> queue) {
if (APIConfigManager.getConfig().getEnabledParticleCountInject()) {
Particle particle;
while ((particle = this.getNewParticles().poll()) != null) {
Map<ParticleTextureSheet, Queue<Particle>> particles = this.getParticles();
particles.computeIfAbsent(particle.getType(),
sheet -> EvictingQueue.create(APIConfigManager.getConfig().getParticleCountLimit()))
.add(particle);
// 不需要判断 EnabledParticleCountInject 了,已在注入时判断,关这个一般都是因为会注入失败,所以不用担心
Particle particle;
int limit = APIConfigManager.getConfig().getParticleCountLimit();
while ((particle = this.getNewParticles().poll()) != null) {
Map<ParticleTextureSheet, Queue<Particle>> particles = this.getParticles();
Queue<Particle> queue1 = particles.computeIfAbsent(particle.getType(),
sheet -> EvictingQueue.create(limit));
// limit 不会改变,这里可以直接判断
if (queue1.size() < limit) {
queue1.add(particle);
} else {
// 这样驱逐队列就没用了但是可以避免内存泄漏
particle.markDead();
}
return null;
} else {
// 恢复原来的功能
return this.getNewParticles().poll();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object ParticleEmittersManager {
/**
* 客户端可视
*/
val clientEmitters = HashMap<UUID, ParticleEmitters>()
val clientEmitters = ConcurrentHashMap<UUID, ParticleEmitters>()

internal fun getCodecFromID(id: String): PacketCodec<RegistryByteBuf, ParticleEmitters>? {
return emittersCodec[id]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,10 @@ abstract class ControlableParticle(
*/
var death: Boolean
get() = dead
set(value) {
dead = value
set(value) = if (value) {
markDead()
} else {
dead = false
}

/**
Expand Down Expand Up @@ -315,6 +317,19 @@ abstract class ControlableParticle(
}
}

/**
* @see ParticleControler.remove()
*/
override fun markDead() {
super.markDead()
// FIXME 原版的驱逐队列满后不会调用 markDead,百分百泄漏,
// 我们的 ParticleManagerMixin 可以确保没问题,
// 但是一旦关闭 ParticleManagerMixin 注入,就绝对有问题
// 粒子的移除方法被原版调用时也要移除 controller 否则会内存泄漏
// 不能放在 controller.remove() 里,因为 markDead 可能在模组外部调用
ControlParticleManager.removeControl(controlUUID)
}

override fun buildGeometry(vertexConsumer: VertexConsumer, camera: Camera, tickDelta: Float) {
if (faceToCamera) {
super.buildGeometry(vertexConsumer, camera, tickDelta)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ object ControlParticleManager {
return controls[uuid]
}

internal fun removeControl(uuid: UUID) {
controls.remove(uuid)
}

fun createControl(uuid: UUID): ParticleControler {
val controler = ParticleControler(uuid)
controls[uuid] = controler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cn.coostack.cooparticlesapi.particles.control

import cn.coostack.cooparticlesapi.particles.Controlable
import cn.coostack.cooparticlesapi.particles.ControlableParticle
import cn.coostack.cooparticlesapi.utils.Math3DUtil
import cn.coostack.cooparticlesapi.utils.RelativeLocation
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
Expand Down Expand Up @@ -67,6 +66,10 @@ class ParticleControler(private val uuid: UUID) : Controlable<ControlableParticl
invokeQueue.forEach {
it(particle)
}
// 防呆用的
if (particle.death) {
ControlParticleManager.removeControl(uuid)
}
}

fun rotateParticleTo(target: RelativeLocation) {
Expand Down Expand Up @@ -102,6 +105,9 @@ class ParticleControler(private val uuid: UUID) : Controlable<ControlableParticl
particle.teleportTo(x, y, z)
}

/**
* @see ControlableParticle.markDead()
*/
override fun remove() {
particle.markDead()
}
Expand Down