Skip to content

Commit

Permalink
fix: Event runner not updating entity archetype/row information after…
Browse files Browse the repository at this point in the history
… modifications when calling multiple listeners
  • Loading branch information
0ffz committed Mar 22, 2024
1 parent 76c156b commit 123e06a
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<Entity> get() = ids.getEntities()

Expand Down Expand Up @@ -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
)

}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,53 @@ 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
delegated = false
}

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()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Int>()
override fun ensure() = event { has<EntityRemoved>() }
}).exec {
data shouldBe 1
entity.remove<Int>()
called++
}

val listener2 = geary.listener(object : ListenerQuery() {
val data by get<String>()
override fun ensure() = event { has<EntityRemoved>() }
}).exec {
data shouldBe ""
}

val entity1 = entity {
set(1)
set("")
}

val entity2 = entity {
set(1)
set("")
}

entity2.removeEntity()
entity1.removeEntity()
called shouldBe 2
}
}

0 comments on commit 123e06a

Please sign in to comment.