Skip to content
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

Query syntax revamp, perf improvements #100

Merged
merged 14 commits into from
Mar 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface AutoScanner {
override fun installSystems() {
scannedSystems.asSequence()
.mapNotNull { it.objectInstance ?: runCatching { it.createInstance() }.getOrNull() }
.filterIsInstance<System>()
.filterIsInstance<System<*>>()
.onEach { geary.pipeline.addSystem(it) }
.map { it::class.simpleName }
.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.mineinabyss.geary.autoscan

import com.mineinabyss.geary.systems.GearySystem
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.RepeatingSystem
import com.mineinabyss.geary.systems.query.GearyQuery

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import com.mineinabyss.geary.addons.dsl.GearyAddonWithDefault
import com.mineinabyss.geary.addons.dsl.GearyDSL
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.configuration.systems.*
import com.mineinabyss.geary.prefabs.systems.TrackPrefabsByKeySystem
import com.mineinabyss.geary.prefabs.systems.createInheritPrefabsOnLoadListener
import com.mineinabyss.geary.prefabs.systems.createTrackPrefabsByKeyListener
import com.mineinabyss.idofront.di.DI

val prefabs by DI.observe<Prefabs>()
Expand All @@ -23,14 +24,13 @@ interface Prefabs {


override fun Prefabs.install() {
geary.pipeline.addSystems(
ParseChildOnPrefab(),
ParseChildrenOnPrefab(),
ParseRelationOnPrefab(),
ParseRelationWithDataSystem(),
TrackPrefabsByKeySystem(),
CopyToInstancesSystem(),
)
createInheritPrefabsOnLoadListener()
createParseChildOnPrefabListener()
createParseChildrenOnPrefabListener()
createParseRelationOnPrefabListener()
createParseRelationWithDataListener()
createTrackPrefabsByKeyListener()
createCopyToInstancesSystem()
geary.pipeline.runOnOrAfter(GearyPhase.INIT_ENTITIES) {
loader.loadOrUpdatePrefabs()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.mineinabyss.geary.prefabs.configuration.components

import com.mineinabyss.geary.components.EntityName
import com.mineinabyss.geary.datatypes.Component
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import kotlinx.serialization.Polymorphic
import kotlinx.serialization.PolymorphicSerializer
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.mineinabyss.geary.prefabs.configuration.systems

import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.configuration.components.CopyToInstances
import com.mineinabyss.geary.systems.GearyListener
import com.mineinabyss.geary.systems.accessors.Pointers
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery

class CopyToInstancesSystem : GearyListener() {
private val Pointers.baseEntity by whenExtendedEntity()

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
val copy = baseEntity.get<CopyToInstances>() ?: return
copy.decodeComponentsTo(target.entity)
}
@OptIn(UnsafeAccessors::class)
fun createCopyToInstancesSystem() = geary.listener(object : ListenerQuery() {
val baseEntity by event.extendedEntity()
}).exec {
val copy = baseEntity.get<CopyToInstances>() ?: return@exec
copy.decodeComponentsTo(entity)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,39 @@ package com.mineinabyss.geary.prefabs.configuration.systems

import com.mineinabyss.geary.components.EntityName
import com.mineinabyss.geary.components.relations.NoInherit
import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.helpers.addParent
import com.mineinabyss.geary.helpers.entity
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.configuration.components.ChildOnPrefab
import com.mineinabyss.geary.prefabs.configuration.components.ChildrenOnPrefab
import com.mineinabyss.geary.prefabs.configuration.components.Prefab
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.accessors.Pointers
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery


class ParseChildOnPrefab : Listener() {
private var Pointers.child by get<ChildOnPrefab>().removable().whenSetOnTarget()

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
entity {
addParent(target.entity)
setAll(child!!.components)
}
child = null
fun createParseChildOnPrefabListener() = geary.listener(object : ListenerQuery() {
val child by get<ChildOnPrefab>()
override fun ensure() = event.anySet(::child)
}).exec {
entity {
addParent(entity)
setAll(child.components)
}
entity.remove<ChildOnPrefab>()
}

class ParseChildrenOnPrefab : Listener() {
private var Pointers.children by get<ChildrenOnPrefab>().removable().whenSetOnTarget()

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
children!!.nameToComponents.forEach { (name, components) ->
entity {
set(EntityName(name))
set(Prefab())
addParent(target.entity)
addRelation<NoInherit, Prefab>()
setAll(components)
}
fun createParseChildrenOnPrefabListener() = geary.listener(object : ListenerQuery() {
var children by get<ChildrenOnPrefab>()
override fun ensure() = event.anySet(::children)
}).exec {
children.nameToComponents.forEach { (name, components) ->
entity {
set(EntityName(name))
set(Prefab())
addParent(entity)
addRelation<NoInherit, Prefab>()
setAll(components)
}
children = null
}
entity.remove<ChildrenOnPrefab>()
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.mineinabyss.geary.prefabs.configuration.systems

import com.mineinabyss.geary.helpers.componentId
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.configuration.components.RelationOnPrefab
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.accessors.Pointers
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery


class ParseRelationOnPrefab : Listener() {
private var Pointers.relation by get<RelationOnPrefab>().removable().whenSetOnTarget()

override fun Pointers.handle() {
try {
val rel: RelationOnPrefab = relation!!
// entity.setRelation(relation.value, entity.parseEntity(relation.key).id)
} finally {
relation = null
}
fun createParseRelationOnPrefabListener() = geary.listener(object : ListenerQuery() {
val relation by get<RelationOnPrefab>()
override fun ensure() = event.anySet(::relation)
}).exec {
try {
val target = entity.lookup(relation.target)?.id ?: return@exec
entity.setRelation(componentId(relation.data::class), target, relation.data)
} finally {
entity.remove<RelationOnPrefab>()
}
}

Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package com.mineinabyss.geary.prefabs.configuration.systems

import com.mineinabyss.geary.datatypes.Records
import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.accessors.Pointers
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.systems.accessors.RelationWithData
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery


class ParseRelationWithDataSystem : Listener() {
private val Records.relationWithData by get<RelationWithData<*, *>>().whenSetOnTarget()

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
val entity = target.entity
val data = relationWithData.data
val targetData = relationWithData.targetData
if (data != null) entity.set(data, relationWithData.relation.id)
else entity.add(relationWithData.relation.id)
if (targetData != null) entity.set(targetData, relationWithData.target.id)
entity.remove<RelationWithData<*, *>>()
}
@OptIn(UnsafeAccessors::class)
fun createParseRelationWithDataListener() = geary.listener(object : ListenerQuery() {
val relationWithData by get<RelationWithData<*, *>>()
override fun ensure() = event.anySet(::relationWithData)
}).exec {
val entity = entity
val data = relationWithData.data
val targetData = relationWithData.targetData
if (data != null) entity.set(data, relationWithData.relation.id)
else entity.add(relationWithData.relation.id)
if (targetData != null) entity.set(targetData, relationWithData.target.id)
entity.remove<RelationWithData<*, *>>()
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
package com.mineinabyss.geary.prefabs.systems

import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.datatypes.family.family
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.events.PrefabLoaded
import com.mineinabyss.geary.prefabs.helpers.inheritPrefabs
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.accessors.Pointers


class InheritPrefabsOnLoad : Listener() {
private val Pointers.loaded by family { has<PrefabLoaded>() }.on(event)

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
target.entity.inheritPrefabs()
}
}
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery

@OptIn(UnsafeAccessors::class)
fun createInheritPrefabsOnLoadListener() = geary.listener(object : ListenerQuery() {
override fun ensure() = event { has<PrefabLoaded>() }
}).exec { entity.inheritPrefabs() }
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package com.mineinabyss.geary.prefabs.systems

import com.mineinabyss.geary.components.relations.NoInherit
import com.mineinabyss.geary.datatypes.Records
import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.components.relations.NoInherit
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.PrefabKey
import com.mineinabyss.geary.prefabs.prefabs
import com.mineinabyss.geary.systems.Listener
import com.mineinabyss.geary.systems.accessors.Pointers


class TrackPrefabsByKeySystem : Listener() {
private val Records.key by get<PrefabKey>().whenSetOnTarget()
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
prefabs.manager.registerPrefab(key, target.entity)
target.entity.addRelation<NoInherit, PrefabKey>()
}
@OptIn(UnsafeAccessors::class)
fun createTrackPrefabsByKeyListener() = geary.listener(object : ListenerQuery() {
val key by get<PrefabKey>()
override fun ensure() = event.anySet(::key)
}).exec {
prefabs.manager.registerPrefab(key, entity)
entity.addRelation<NoInherit, PrefabKey>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class PrefabTests {
}

@Test
fun `should track prefabs when key added`(){
fun `should track prefabs when key added`() {
// arrange & act
val prefab = entity { set(testKey) }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.mineinabyss.geary.prefabs

import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import com.mineinabyss.geary.serialization.formats.YamlFormat
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import io.kotest.matchers.shouldBe
import kotlinx.serialization.Polymorphic
import kotlinx.serialization.PolymorphicSerializer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.mineinabyss.geary.uuid

import com.mineinabyss.geary.addons.dsl.GearyAddonWithDefault
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.uuid.systems.TrackUuidOnAdd
import com.mineinabyss.geary.uuid.systems.UnTrackUuidOnRemove
import com.mineinabyss.geary.uuid.systems.createTrackUUIDOnAddListener
import com.mineinabyss.geary.uuid.systems.createUntrackUuidOnRemoveListener
import com.mineinabyss.idofront.di.DI

val uuid2Geary by DI.observe<UUID2GearyMap>()
Expand All @@ -12,9 +11,7 @@ object UUIDTracking : GearyAddonWithDefault<UUID2GearyMap> {
override fun default() = SimpleUUID2GearyMap()

override fun UUID2GearyMap.install() {
geary.pipeline.addSystems(
TrackUuidOnAdd(),
UnTrackUuidOnRemove()
)
createTrackUUIDOnAddListener()
createUntrackUuidOnRemoveListener()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,23 @@ package com.mineinabyss.geary.uuid.systems

import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuid4
import com.mineinabyss.geary.annotations.optin.UnsafeAccessors
import com.mineinabyss.geary.systems.GearyListener
import com.mineinabyss.geary.systems.accessors.Pointers

import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery
import com.mineinabyss.geary.uuid.components.RegenerateUUIDOnClash
import com.mineinabyss.geary.uuid.uuid2Geary

class TrackUuidOnAdd : GearyListener() {
var Pointers.uuid by get<Uuid>().whenSetOnTarget()
val Pointers.regenerateUUIDOnClash by get<RegenerateUUIDOnClash>().orNull().on(target)

@OptIn(UnsafeAccessors::class)
override fun Pointers.handle() {
if (uuid in uuid2Geary)
if (regenerateUUIDOnClash != null) {
val newUuid = uuid4()
uuid = newUuid
uuid2Geary[newUuid] = target.entity
} else error("Tried tracking entity $target.entity with already existing uuid $uuid")
else
uuid2Geary[uuid] = target.entity
}
fun createTrackUUIDOnAddListener() = geary.listener(object : ListenerQuery() {
var uuid by get<Uuid>()
val regenerateUUIDOnClash by get<RegenerateUUIDOnClash>().orNull()
override fun ensure() = event.anySet(::uuid)
}).exec {
if (uuid in uuid2Geary)
if (regenerateUUIDOnClash != null) {
val newUuid = uuid4()
uuid = newUuid
uuid2Geary[newUuid] = entity
} else error("Tried tracking entity $entity with already existing uuid $uuid")
else
uuid2Geary[uuid] = entity
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@ package com.mineinabyss.geary.uuid.systems

import com.benasher44.uuid.Uuid
import com.mineinabyss.geary.components.events.EntityRemoved
import com.mineinabyss.geary.datatypes.Records
import com.mineinabyss.geary.datatypes.family.family
import com.mineinabyss.geary.systems.GearyListener
import com.mineinabyss.geary.systems.accessors.Pointers

import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery
import com.mineinabyss.geary.uuid.uuid2Geary

class UnTrackUuidOnRemove : GearyListener() {
private val Pointers.uuid by get<Uuid>().on(target)
private val Pointers.removed by family { has<EntityRemoved>() }.on(event)

override fun Pointers.handle() {
uuid2Geary.remove(uuid)
}
}
fun createUntrackUuidOnRemoveListener() = geary.listener(object : ListenerQuery() {
val uuid by get<Uuid>()
override fun ensure() = event.invoke { has<EntityRemoved>() }
}).exec { uuid2Geary.remove(uuid) }
Loading
Loading