diff --git a/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/Archetype.kt b/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/Archetype.kt index 55e066809..0885909fc 100644 --- a/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/Archetype.kt +++ b/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/Archetype.kt @@ -21,9 +21,9 @@ class Archetype internal constructor( val type: EntityType, var id: Int ) { - private val records get() = archetypes.records - private val archetypeProvider get() = archetypes.archetypeProvider - private val eventRunner get() = archetypes.eventRunner + private val records = archetypes.records + private val archetypeProvider = archetypes.archetypeProvider + private val eventRunner = archetypes.eventRunner val entities: Sequence get() = ids.getEntities() @@ -298,11 +298,10 @@ class Archetype internal constructor( event.addRelation(eventType, componentId, noEvent = true) records.runOn(event) { eventArc, eventRow -> eventRunner.callEvent( - this, row, - eventArc, eventRow, - null, null + getEntity(row), + eventArc.getEntity(eventRow), + null ) - } } } diff --git a/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/ArchetypeEventRunner.kt b/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/ArchetypeEventRunner.kt index 37685ff8a..e2b84e4c5 100644 --- a/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/ArchetypeEventRunner.kt +++ b/geary-core/src/commonMain/kotlin/com/mineinabyss/geary/engine/archetypes/ArchetypeEventRunner.kt @@ -11,23 +11,37 @@ class ArchetypeEventRunner : EventRunner { private val records get() = archetypes.records override fun callEvent(target: Entity, event: Entity, source: Entity?) { - records.runOn(target) { targetArc, targetRow -> - records.runOn(event) { eventArc, eventRow -> - if(source != null) records.runOn(source) { sourceArc, sourceRow -> - callEvent(targetArc, targetRow, eventArc, eventRow, sourceArc, sourceRow) - } else callEvent(targetArc, targetRow, eventArc, eventRow, null, null) +// records.runOn(target) { targetArc, targetRow -> +// records.runOn(event) { eventArc, eventRow -> +// if(source != null) records.runOn(source) { sourceArc, sourceRow -> +// callEvent(targetArc, targetRow, eventArc, eventRow, sourceArc, sourceRow) +// } else callEvent(targetArc, targetRow, eventArc, eventRow, null, null) +// } +// } + + var targetArc: Archetype = archetypes.archetypeProvider.rootArchetype + var targetRow: Int = -1 + var eventArc: Archetype = archetypes.archetypeProvider.rootArchetype + var eventRow: Int = -1 + var sourceArc: Archetype? = null + var sourceRow: Int? = null + fun updateArcsAndRows() { + records.runOn(target) { arch, row -> + targetArc = arch + targetRow = row + } + records.runOn(event) { arch, row -> + eventArc = arch + eventRow = row + } + if (source != null) records.runOn(source) { arch, row -> + sourceArc = arch + sourceRow = row } } - } - fun callEvent( - targetArc: Archetype, - targetRow: Int, - eventArc: Archetype, - eventRow: Int, - sourceArc: Archetype?, - sourceRow: Int? - ) { + updateArcsAndRows() + fun QueriedEntity.reset(arch: Archetype, row: Int) { originalArchetype = arch originalRow = row @@ -35,11 +49,15 @@ class ArchetypeEventRunner : EventRunner { } fun callListener(listener: Listener<*>) { + updateArcsAndRows() val query = listener.query query.event.reset(eventArc, eventRow) query.reset(targetArc, targetRow) - if(sourceArc != null && sourceRow != null) - query.source.reset(sourceArc, sourceRow) + sourceArc?.let { arc -> + sourceRow?.let { row -> + query.source.reset(arc, row) + } + } listener.run() } diff --git a/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/datatypes/GearyEntityTests.kt b/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/datatypes/GearyEntityTests.kt index 2bb04095c..ce48b3a9e 100644 --- a/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/datatypes/GearyEntityTests.kt +++ b/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/datatypes/GearyEntityTests.kt @@ -157,6 +157,15 @@ internal class GearyEntityTests : GearyTest() { entity.getAllPersisting().shouldContainExactly("Test") } + @Test + fun `should correctly remove entities`() { + val entity = entity { set("Test") } + + entity.exists() shouldBe true + entity.removeEntity() + entity.exists() shouldBe false + } + @Nested inner class ChildTest { @Test diff --git a/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/events/EntityRemoveListenerTest.kt b/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/events/EntityRemoveListenerTest.kt new file mode 100644 index 000000000..fb8393c84 --- /dev/null +++ b/geary-core/src/jvmTest/kotlin/com/mineinabyss/geary/events/EntityRemoveListenerTest.kt @@ -0,0 +1,47 @@ +package com.mineinabyss.geary.events + +import com.mineinabyss.geary.components.events.EntityRemoved +import com.mineinabyss.geary.helpers.entity +import com.mineinabyss.geary.helpers.tests.GearyTest +import com.mineinabyss.geary.modules.geary +import com.mineinabyss.geary.systems.builders.listener +import com.mineinabyss.geary.systems.query.ListenerQuery +import io.kotest.matchers.shouldBe +import kotlin.test.Test + +class EntityRemoveListenerTest : GearyTest() { + @Test + fun `should correctly run multiple listeners on single event`() { + var called = 0 + + val listener1 = geary.listener(object : ListenerQuery() { + val data by get() + override fun ensure() = event { has() } + }).exec { + data shouldBe 1 + entity.remove() + called++ + } + + val listener2 = geary.listener(object : ListenerQuery() { + val data by get() + override fun ensure() = event { has() } + }).exec { + data shouldBe "" + } + + val entity1 = entity { + set(1) + set("") + } + + val entity2 = entity { + set(1) + set("") + } + + entity2.removeEntity() + entity1.removeEntity() + called shouldBe 2 + } +}