Skip to content

Commit

Permalink
(#138) optimize family notifications for world.entity and entity.conf…
Browse files Browse the repository at this point in the history
…igure
  • Loading branch information
Quillraven authored Apr 2, 2024
1 parent 3225313 commit 3154335
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/commonMain/kotlin/com/github/quillraven/fleks/entity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,15 @@ class EntityService(
@PublishedApi
internal val createCtx = EntityCreateContext(compService, compMasks)

@PublishedApi
internal var createId = -1

@PublishedApi
internal val updateCtx = EntityUpdateContext(compService, compMasks)

@PublishedApi
internal var updateId = -1

/**
* Flag that indicates if an iteration of an [IteratingSystem] is currently in progress.
* In such cases entities will not be removed immediately.
Expand Down Expand Up @@ -460,10 +466,14 @@ class EntityService(
if (entity.id >= compMasks.size) {
compMasks[entity.id] = BitArray(64)
}
val compMask = compMasks[entity.id]

val prevCreateId = createId
createId = entity.id
createCtx.configuration(entity)
createId = prevCreateId

// update families
val compMask = compMasks[entity.id]
world.allFamilies.forEach { it.onEntityAdded(entity, compMask) }

// trigger optional add hook
Expand All @@ -477,8 +487,18 @@ class EntityService(
* Notifies all [families][World.allFamilies].
*/
inline fun configure(entity: Entity, configuration: EntityUpdateContext.(Entity) -> Unit) {
val compMask = compMasks[entity.id]
val skipFamilyNotify = updateId == entity.id || createId == entity.id

val prevUpdateId = updateId
updateId = entity.id
updateCtx.configuration(entity)
updateId = prevUpdateId

// notify families
if (skipFamilyNotify) {
return
}
val compMask = compMasks[entity.id]
world.allFamilies.forEach { it.onEntityCfgChanged(entity, compMask) }
}

Expand Down
50 changes: 50 additions & 0 deletions src/commonTest/kotlin/com/github/quillraven/fleks/WorldTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -976,4 +976,54 @@ internal class WorldTest {
assertEquals(1, world.numEntities)
assertEquals(10, world.asEntityBag().first().id)
}

@Test
fun testNestedFamilyNotificationCreate() {
var numAdd = 0
val world = configureWorld {
val family = world.family { all(WorldTestComponent2) }
families {
onAdd(family) { entity ->
++numAdd
assertEquals(entity, Entity(0, 0u))
}
}
}

// verify that family notification is only called once at the end of world.entity
world.entity { entity ->
entity += WorldTestComponent2()
entity.configure {
it += WorldTestComponent2()
}
assertEquals(0, numAdd)
}
assertEquals(1, numAdd)
}

@Test
fun testNestedFamilyNotificationConfigure() {
var numAdd = 0
val world = configureWorld {
val family = world.family { all(WorldTestComponent2) }
families {
onAdd(family) { entity ->
++numAdd
assertEquals(entity, Entity(0, 0u))
}
}
}
val entity = world.entity {}

// verify that notification is called only once at the end of the outer configure call
with(world) {
entity.configure {
entity.configure {
it += WorldTestComponent2()
}
assertEquals(0, numAdd)
}
assertEquals(1, numAdd)
}
}
}

0 comments on commit 3154335

Please sign in to comment.