-
Notifications
You must be signed in to change notification settings - Fork 20
Serialization
Simon edited this page Oct 17, 2023
·
14 revisions
Serialization and Deserialization in Fleks can be achieved via the snapshot
functionality of the world
. A Snapshot
is a container for the components and tags of an entity.
data class Snapshot(
val components: List<Component<*>>,
val tags: List<UniqueId<*>>,
)
Fleks uses Kotlinx Serialization which is the standard for Kotlin multiplatform applications. Fleks also uses the stable Json
library.
Serializing an entity is straight forward:
val entity = Entity(id = 0, version = 0u)
// encode an entity
val jsonStr = Json.encodeToString(entity0) // {"id":0,"version":0}
// decode an entity
val decodedEntity: Entity = Json.decodeFromString(jsonStr)
Serializing a snapshot
requires some minor setup work. First, you need to annotate your serializable components/tags with @Serializable
. Second, you need to register your components/tags as a subclass of Component
/UniqueId
. Finally, you need to configure Json
to allow structured map keys since an entity is a combination of its id and version. Here is an example:
@Serializable
data object VisibleTag : EntityTag()
@Serializable
data class Speed(val max:Int) : Component<Speed> {
override fun type() = Speed
companion object : ComponentType<Speed>()
}
@Serializable
data class Graphic(val texture:String) : Component<Graphic> {
override fun type() = Graphic
companion object : ComponentType<Graphic>()
}
fun main() {
val world = configureWorld { }
world.entity {
it += Speed(3)
it += Graphic("mySprite.png")
it += VisibleTag
}
// configure Json's serializersModule and allow structured map keys
val json = Json {
serializersModule = SerializersModule {
// register components
polymorphic(Component::class) {
subclass(Speed::class, Speed.serializer())
subclass(Graphic::class, Graphic.serializer())
}
// register tags
polymorphic(UniqueId::class) {
subclass(VisibleTag::class, VisibleTag.serializer())
}
}
allowStructuredMapKeys = true // to support entity id + version as a key in a map data structure
}
val snapshot: Map<Entity, Snapshot> = world.snapshot()
val snapshotJson = json.encodeToString(snapshot) // [{"id":0,"version":0},{"components":[{"type":"com.github.quillraven.fleks.Graphic","texture":"mySprite.png"},{"type":"com.github.quillraven.fleks.Speed","max":3}],"tags":[{"type":"com.github.quillraven.fleks.VisibleTag"}]}]
// clear world and load encoded snapshot from before
world.removeAll(clearRecycled = true)
world.loadSnapshot(json.decodeFromString(snapshotJson))
}