Skip to content

Commit

Permalink
feat: instances component for creating prefab instances in config
Browse files Browse the repository at this point in the history
chore: Use inner serializer for InheritPrefabs
fix: not resetting delegated status in forEach call, resulting in incorrect entities returned in queries.
  • Loading branch information
0ffz committed Mar 28, 2024
1 parent ffebadb commit 1ab06be
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ class PrefabLoader {
if (logger.config.minSeverity <= Severity.Debug)
logger.e("Could not read prefab $path:\n\u001B[37m${it.stackTraceToString()}")
else
logger.e("Could not read prefab $path:\n\u001B[37m${it.message}")
logger.e(
"Could not read prefab $path:\n\u001B[37m${
it.stackTraceToString().lines().take(5).joinToString("\n")
}"
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface Prefabs {
createInheritPrefabsOnLoadListener()
createParseChildOnPrefabListener()
createParseChildrenOnPrefabListener()
createParseInstancesOnPrefabListener()
createParseRelationOnPrefabListener()
createParseRelationWithDataListener()
createTrackPrefabsByKeyListener()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.mineinabyss.geary.datatypes.Component
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
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
Expand All @@ -23,7 +22,7 @@ class ChildrenOnPrefab(
) {
class Serializer : InnerSerializer<Map<String, List<Component>>, ChildrenOnPrefab>(
"geary:children",
MapSerializer(String.serializer(), PolymorphicListAsMapSerializer.of(PolymorphicSerializer(Component::class))),
MapSerializer(String.serializer(), PolymorphicListAsMapSerializer.ofComponents()),
{ ChildrenOnPrefab(it) },
{ it.nameToComponents },
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package com.mineinabyss.geary.prefabs.configuration.components

import com.mineinabyss.geary.prefabs.PrefabKey
import kotlinx.serialization.SerialName
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.SetSerializer

/**
* > geary:inherit
*
* Will make this entity an instance of all entities defined in [from]
*/
@Serializable
@SerialName("geary:inherit")
@Serializable(with = InheritPrefabs.Serializer::class)
class InheritPrefabs(
val from: Set<PrefabKey>
)
) {
class Serializer : InnerSerializer<Set<PrefabKey>, InheritPrefabs>(
"geary:inherit",
SetSerializer(PrefabKey.serializer()),
{ InheritPrefabs(it) },
{ it.from }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import kotlinx.serialization.Polymorphic
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer

/**
* > geary:children
*
* A component that will add a list of named children to this entity.
*
* The keys will be used to set an extra [EntityName] component.
*/
@Serializable(with = InstancesOnPrefab.Serializer::class)
class InstancesOnPrefab(
val nameToComponents: Map<String, List<@Polymorphic Component>>
) {
class Serializer : InnerSerializer<Map<String, List<Component>>, InstancesOnPrefab>(
"geary:instances",
MapSerializer(String.serializer(), PolymorphicListAsMapSerializer.ofComponents()),
{ InstancesOnPrefab(it) },
{ it.nameToComponents },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mineinabyss.geary.prefabs.configuration.systems

import com.mineinabyss.geary.components.relations.NoInherit
import com.mineinabyss.geary.helpers.entity
import com.mineinabyss.geary.modules.GearyModule
import com.mineinabyss.geary.prefabs.PrefabKey
import com.mineinabyss.geary.prefabs.configuration.components.InstancesOnPrefab
import com.mineinabyss.geary.prefabs.configuration.components.Prefab
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery

fun GearyModule.createParseInstancesOnPrefabListener() = listener(object : ListenerQuery() {
val instances by get<InstancesOnPrefab>()
val prefabKey by get<PrefabKey>()
override fun ensure() = event.anyFirstSet(::instances, ::prefabKey)
}).exec {
entity.addRelation<NoInherit, InstancesOnPrefab>()
instances.nameToComponents.forEach { (name, components) ->
entity {
set(PrefabKey.of(prefabKey.namespace, name))
set(Prefab())
extend(entity)
addRelation<NoInherit, Prefab>()
setAll(components)
}
logger.d("Created instance $name of prefab $prefabKey")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class CachedQueryRunner<T : Query> internal constructor(val query: T) {
try {
while (row < upTo) {
query.originalRow = row
query.delegated = false
run(query)
row++
}
Expand Down Expand Up @@ -77,6 +78,7 @@ class CachedQueryRunner<T : Query> internal constructor(val query: T) {
fun prepareRow(): Boolean {
if (row >= upTo) return false
query.originalRow = row
query.delegated = false
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ class SimpleQueryTest : GearyTest() {
nums.sorted() shouldBe (0..9).toList()
}

@Test
fun `entities should return matched entities correctly`() {
val query = geary.queryManager.trackQuery(MyQuery())

val nums = mutableListOf<Int>()
query.entities().forEach {
nums.add(it.get<Int>()!!)
}

nums.sorted() shouldBe (0..9).toList()
}

@Test
fun `first should correctly return first matched entity`() {
val query = geary.queryManager.trackQuery(MyQuery())
Expand Down

0 comments on commit 1ab06be

Please sign in to comment.