fix some multi threading crashes, gui: implement popping of specific element

This commit is contained in:
Bixilon 2022-02-26 19:32:26 +01:00
parent 0a8c1f974e
commit a6e19d0896
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 36 additions and 10 deletions

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.data.entities.meta
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.concurrent.lock.SimpleLock
import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.container.stack.ItemStack
@ -39,6 +40,7 @@ import java.util.*
class EntityData(
val connection: PlayConnection,
) {
val lock = SimpleLock()
val sets: EntityDataHashMap = EntityDataHashMap()
override fun toString(): String {
@ -57,7 +59,6 @@ class EntityData(
EntityDataDataTypes.BOOLEAN -> buffer.readBoolean()
EntityDataDataTypes.VEC3I -> Vec3i(buffer.readInt(), buffer.readInt(), buffer.readInt())
EntityDataDataTypes.ITEM_STACK -> buffer.readItemStack()
EntityDataDataTypes.ITEM_STACK -> buffer.readItemStack()
EntityDataDataTypes.ROTATION -> ArmorStandArmRotation(buffer.readFloat(), buffer.readFloat(), buffer.readFloat())
EntityDataDataTypes.BLOCK_POSITION -> buffer.readBlockPosition()
EntityDataDataTypes.OPT_CHAT -> buffer.readOptional { buffer.readChatComponent() }
@ -109,15 +110,20 @@ class EntityData(
inner class EntityDataHashMap : Int2ObjectOpenHashMap<Any>() {
operator fun <K> get(field: EntityDataFields): K {
val index: Int = this@EntityData.connection.registries.getEntityMetaDataIndex(field) ?: return field.defaultValue.unsafeCast() // Can not find field.
get(index)?.let {
try {
return it as K
} catch (exception: ClassCastException) {
Log.log(LogMessageType.OTHER, level = LogLevels.WARN, message = exception)
lock.acquire()
try {
val index: Int = this@EntityData.connection.registries.getEntityMetaDataIndex(field) ?: return field.defaultValue.unsafeCast() // Can not find field.
get(index)?.let {
try {
return it as K
} catch (exception: ClassCastException) {
Log.log(LogMessageType.OTHER, level = LogLevels.WARN, message = exception)
}
}
return field.defaultValue as K
} finally {
lock.release()
}
return field.defaultValue as K
}
fun getPose(field: EntityDataFields): Poses? {

View File

@ -82,7 +82,7 @@ class WorldEntities : Iterable<Entity> {
@Deprecated("ToDo: Lock")
override fun iterator(): Iterator<Entity> {
return idEntityMap.toSynchronizedMap().values.iterator()
return uuidEntityMap.toSynchronizedMap().values.iterator()
}
fun getInRadius(position: Vec3d, distance: Double, check: (Entity) -> Boolean): List<Entity> {

View File

@ -243,7 +243,25 @@ class GUIManager(
}
fun pop(element: GUIElement) {
TODO("Not yet implemented")
if (elementOrder.isEmpty()) {
return
}
val index = elementOrder.indexOf(element)
if (index < 0) {
return
}
element.onClose()
elementOrder.removeAt(index)
if (index == 0) {
elementOrder.firstOrNull()?.onOpen()
}
if (elementOrder.isEmpty()) {
renderWindow.inputHandler.inputHandler = null
guiRenderer.popper.clear()
guiRenderer.dragged.element = null
}
}
fun pop() {

View File

@ -30,7 +30,9 @@ class EntityDataS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
override fun handle(connection: PlayConnection) {
val entity = connection.world.entities[entityId] ?: return
entity.data.lock.lock()
entity.data.sets.putAll(data.sets)
entity.data.lock.unlock()
connection.fireEvent(EntityDataChangeEvent(connection, this))
}