From a6e19d0896431c0b2ac7ccc6737daef58aac4615 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 26 Feb 2022 19:32:26 +0100 Subject: [PATCH] fix some multi threading crashes, gui: implement popping of specific element --- .../minosoft/data/entities/meta/EntityData.kt | 22 ++++++++++++------- .../minosoft/data/world/WorldEntities.kt | 2 +- .../gui/rendering/gui/gui/GUIManager.kt | 20 ++++++++++++++++- .../packets/s2c/play/entity/EntityDataS2CP.kt | 2 ++ 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityData.kt b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityData.kt index 80f1f3504..5e56abc39 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityData.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityData.kt @@ -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() { operator fun 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? { diff --git a/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt b/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt index 6b461a794..c92793bb0 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt @@ -82,7 +82,7 @@ class WorldEntities : Iterable { @Deprecated("ToDo: Lock") override fun iterator(): Iterator { - return idEntityMap.toSynchronizedMap().values.iterator() + return uuidEntityMap.toSynchronizedMap().values.iterator() } fun getInRadius(position: Vec3d, distance: Double, check: (Entity) -> Boolean): List { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt index d09b29609..d5ea2af5b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIManager.kt @@ -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() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/EntityDataS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/EntityDataS2CP.kt index d81916e6b..a00a1c670 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/EntityDataS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/EntityDataS2CP.kt @@ -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)) }