Entity: cache id

This workarounds ANOTHER stupid stdlib bug. While entities are ticking SOMETIMES the lock *of the sync* is not releases after acquiring the read lock and no other threads can acquire the lock. I debugged this and it is a race condition in the ReentrantReadWriteLock (or in the synchronizer) class. Pretty ironic.
This commit is contained in:
Moritz Zwerger 2025-03-06 00:18:28 +01:00
parent 7d3f8aece1
commit 97e6cd11cf
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
3 changed files with 21 additions and 4 deletions

View File

@ -55,10 +55,20 @@ abstract class Entity(
) : Initializable, EntityAttachable {
private var flags: Int by data(FLAGS_DATA, 0x00) { it.toInt() }
protected val random = Random()
var _id: Int? = null
var _uuid: UUID? = null
val id: Int?
get() = session.world.entities.getId(this)
get() {
if (_id != null) return _id
_id = session.world.entities.getId(this)
return _id
}
open val uuid: UUID?
get() = session.world.entities.getUUID(this)
get() {
if (_uuid != null) return _uuid
_uuid = session.world.entities.getUUID(this)
return _uuid
}
@Deprecated(message = "Use session.version", replaceWith = ReplaceWith("session.version.versionId"))
protected val versionId: Int get() = session.version.versionId
@ -95,6 +105,7 @@ abstract class Entity(
open val canRaycast: Boolean get() = true
var age = 0
private set

View File

@ -96,6 +96,8 @@ class WorldEntities : Iterable<Entity> {
fun remove(entity: Entity) {
lock.lock()
entity._id = null
entity._uuid = null
if (entity !is LocalPlayerEntity && !entities.remove(entity)) {
lock.unlock()
return
@ -112,6 +114,8 @@ class WorldEntities : Iterable<Entity> {
lock.unlock()
return
}
entity._id = null
entity._uuid = null
if (entity is LocalPlayerEntity) {
idEntityMap.put(entityId, entity)
lock.unlock()
@ -192,6 +196,8 @@ class WorldEntities : Iterable<Entity> {
fun clear(session: PlaySession, local: Boolean = false) {
this.lock.lock()
for (entity in this.entities) {
entity._id = null
entity._uuid = null
if (!local && entity is LocalPlayerEntity) continue
entityIdMap.remove(entity)?.let { idEntityMap.remove(it) }
entityUUIDMap.remove(entity)?.let { uuidEntityMap.remove(it) }

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger
* Copyright (C) 2020-2025 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -62,11 +62,11 @@ class EntityObjectSpawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
}
entity.startInit()
entity.setObjectData(data)
velocity?.let { entity.physics.velocity = it }
}
override fun handle(session: PlaySession) {
session.world.entities.add(entityId, entityUUID, entity)
velocity?.let { entity.physics.velocity = it }
}
override fun log(reducedLog: Boolean) {