New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: API to get a family of entities. #48
Comments
Hi @Kietyo , I just released a version yesterday that contains this feature. Here is a snippet from the ReadMe. The important part is the fun main() {
val world = World {}
val e1 = w.entity {
add<MoveComponent> { speed = 70f }
}
val e2 = w.entity {
add<MoveComponent> { speed = 50f }
add<DeadComponent>()
}
val e3 = w.entity {
add<MoveComponent> { speed = 30f }
}
// get family for entities with a MoveComponent
// and without a DeadComponent
val family = world.family(
allOf = arrayOf(MoveComponent::class),
noneOf = arrayOf(DeadComponent::class),
)
// you can sort entities of a family
val moves = world.mapper<MoveComponent>()
family.sort(compareEntity { entity1, entity2 -> moves[entity1].speed.compareTo(moves[entity2].speed) })
// And you can iterate over entities of a family.
// In this example it will iterate in following order:
// 1) e3
// 2) e1
family.forEach { entity ->
// do something with the entity
}
} Does this cover your needs for this use case? |
Thanks! This does, are you supporting the korge-fleks version BTW? Cause that's the version I'm using: |
I was afraid that you say that 😅 Any help is appreciated! I myself try to update that version by end of June. I need to make a small release to the JVM version again this week for some Bugfixes and I try to support your Family listener idea. This version will then be the base for the next KMP Version as well. Thank you for your input and suggestions! And sorry for the delay with the KMP part. This will be easier in the future once those two versions get merged into one 😉 |
I see, I've started contributing to the korge-fleks version actually... fyi korlibs-archive/korge-next#715 It's easier for me to modify that version since I already have the korge-next repo integrated into my workflow. |
Thanks for notifing me here 👍 |
I think in the |
@Kietyo / @jobe-m : I tried something now for the /**
* Interface of a [family][Family] listener that gets notified when an
* [entity][Entity] gets added to, or removed from a family.
*/
interface FamilyListener {
/**
* Function that gets called when an [entity][Entity] gets added to a [family][Family].
*/
fun onEntityAdded(entity: Entity) = Unit
/**
* Function that gets called when an [entity][Entity] gets removed from a [family][Family].
*/
fun onEntityRemoved(entity: Entity) = Unit
} The family itself has three functions: /**
* Adds the given [listener] to the list of [FamilyListener].
*/
fun addFamilyListener(listener: FamilyListener) = listeners.add(listener)
/**
* Removes the given [listener] from the list of [FamilyListener].
*/
fun removeFamilyListener(listener: FamilyListener) = listeners.removeValue(listener)
/**
* Returns true if an only if the given [listener] is part of the list of [FamilyListener].
*/
operator fun contains(listener: FamilyListener) = listener in listeners That gives users the possibility to do something like this: fun main() {
val familyListener = object : FamilyListener {
override fun onEntityAdded(entity: Entity) {
// do something when an entity gets added to the family
}
override fun onEntityRemoved(entity: Entity) {
// do something when an entity gets removed of a family
}
}
val world = World {}
val family = world.family(
allOf = arrayOf(MoveComponent::class),
noneOf = arrayOf(DeadComponent::class),
)
family.addFamilyListener(familyListener)
// this will notify the listener via its onEntityAdded function
val entity = world.entity {
add<MoveComponent>()
add<DeadComponent>()
}
// this will notify the listener via its onEntityRemoved function
world.remove(entity)
} I think this is fine but there is a special case that I can think of, where this won't work. When a user is creating entities in a system's constructor then the My proposal would be to do something similar like we do it with @AllOf([Cmp1::clas, Cmp2::class])
@NoneOf([Cmp3::class])
class MyFamilyListener : FamilyListener {
override fun onEntityAdded(entity: Entity) {
}
override fun onEntityRemoved(entity: Entity) {
}
}
val w = World {
familyListener<MyFamilyListener>()
} or for the KMP version: class MyFamilyListener : FamilyListener(
allOf = arrayOf(Cmp1::class, Cmp2::class),
noneOf = arrayOf(Cmp3::class)
) {
override fun onEntityAdded(entity: Entity) {
}
override fun onEntityRemoved(entity: Entity) {
}
}
val w = World {
familyListener(::MyFamilyListener)
} What do you think about that? |
I like the proposal, thanks! |
The proposal looks good! |
I will close this issue as well. It is part of #53. If you have feedback then please let me know in the PR. Thanks! |
I want a way to be able to easily get a family of entities with certain components that's decoupled from the systems.
Example:
The family container should be automatically updated on addition/removal of entities and addition/removal of their components.
The text was updated successfully, but these errors were encountered: