Skip to content

Commit

Permalink
Add support for subkeys in prefab config, use camelCase for all Seria…
Browse files Browse the repository at this point in the history
…lNames
  • Loading branch information
0ffz committed Dec 26, 2023
1 parent 5b6f86d commit fadef6f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* > geary:copy_to_instances
*
* A component prefabs may use to specify a list of components which should be copied to instances of itself.
*
* These components are not active on the prefab itself and will be instantiated for every new instance of this class.
* Components may be defined as simply [temporary] or [persisting], where persisting components will be added as such
* in the Engine.
*/
@Serializable
@SerialName("geary:copy_to_instances")
@SerialName("geary:copyToInstances")
data class CopyToInstances(
private val temporary: Set<@Polymorphic Component> = setOf(),
private val persisting: Set<@Polymorphic Component> = setOf(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,24 @@ class GearyComponentSerializer : KSerializer<GearyComponent> {

}

class ComponentListAsMapSerializer : KSerializer<List<GearyComponent>> {
class ComponentListAsMapSerializer(
val namespaces: List<String> = listOf(),
val prefix: String = "",
) : KSerializer<List<GearyComponent>> {
val keySerializer = String.serializer()
val valueSerializer = GearyComponentSerializer()

override val descriptor: SerialDescriptor
get() = MapSerializer(keySerializer, valueSerializer).descriptor

fun <T> CompositeDecoder.decodeMapValue(valueSerializer: KSerializer<T>): T {
val newDescriptor = MapSerializer(keySerializer, valueSerializer).descriptor
val newIndex = decodeElementIndex(newDescriptor)
return decodeSerializableElement(newDescriptor, newIndex, valueSerializer)
}

override fun deserialize(decoder: Decoder): List<GearyComponent> {
val namespaces = mutableListOf<String>()
val namespaces = namespaces.toMutableList()
val components = mutableListOf<GearyComponent>()
val compositeDecoder = decoder.beginStructure(descriptor)
while (true) {
Expand All @@ -47,25 +56,24 @@ class ComponentListAsMapSerializer : KSerializer<List<GearyComponent>> {

val startIndex = components.size * 2
val key: String = compositeDecoder.decodeSerializableElement(descriptor, startIndex + index, keySerializer)
when (key) {
"namespaces" -> {
when {
key == "namespaces" -> {
val valueSerializer = ListSerializer(String.serializer())
val newIndex =
compositeDecoder.decodeElementIndex(MapSerializer(keySerializer, valueSerializer).descriptor)
val namespacesList = compositeDecoder.decodeSerializableElement(descriptor, newIndex, valueSerializer)
val namespacesList = compositeDecoder.decodeMapValue(valueSerializer)
namespaces.addAll(namespacesList)
}

key.endsWith("*") -> {
val innerSerializer = ComponentListAsMapSerializer(namespaces, key.removeSuffix("*"))
components.addAll(compositeDecoder.decodeMapValue(innerSerializer))
}

else -> {
val foundValueSerializer =
serializableComponents.serializers.getSerializerFor(key, GearyComponent::class, namespaces) as? KSerializer<Any>
?: error("No component serializer registered for $key")
val newDescriptor = MapSerializer(keySerializer, foundValueSerializer).descriptor
val newIndex = compositeDecoder.decodeElementIndex(newDescriptor)
val decodedValue = compositeDecoder.decodeSerializableElement<Any>(
descriptor = newDescriptor,
index = newIndex,
deserializer = foundValueSerializer,
)
val foundValueSerializer = serializableComponents.serializers
.getSerializerFor("$prefix$key", GearyComponent::class, namespaces) as? KSerializer<Any>
?: error("No component serializer registered for $key")

val decodedValue = compositeDecoder.decodeMapValue(foundValueSerializer)
components += decodedValue
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

object PrefabKeySerializer : KSerializer<PrefabKey> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("geary:prefab_key", PrimitiveKind.STRING)
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("geary:prefabKey", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): PrefabKey {
return PrefabKey.of(decoder.decodeString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlin.reflect.KClassifier
* Represents the [class][kClass] a component entity is responsible for.
*/
@Serializable
@SerialName("geary:component_info")
@SerialName("geary:componentInfo")
data class ComponentInfo(
val kClass: KClassifier
)

0 comments on commit fadef6f

Please sign in to comment.