commonMain.ru.casperix.spine.json.JsonSkeletonLoader.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spine-jvm Show documentation
Show all versions of spine-jvm Show documentation
Signals for all occasions
The newest version!
package ru.casperix.spine.json
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import ru.casperix.atlas.Atlas
import ru.casperix.atlas.AtlasLoader
import ru.casperix.multiplatform.PlatformMisc
import ru.casperix.multiplatform.loader.ResourceLoadError
import ru.casperix.multiplatform.loader.resourceLoader
import ru.casperix.signals.concrete.EitherFuture
import ru.casperix.signals.concrete.EitherSignal
import ru.casperix.spine.json.component.*
object JsonSkeletonLoader {
private val cache = mutableMapOf>()
data class SkeletonLink(val skeletonFile: String, val atlasFile: String)
private val JSON = Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule {
polymorphic(AttachmentJson::class) {
subclass(RegionAttachmentJson::class)
subclass(MeshAttachmentJson::class)
subclass(LinkedMeshAttachmentJson::class)
subclass(BoundingBoxAttachmentJson::class)
subclass(PathAttachmentJson::class)
subclass(PointAttachmentJson::class)
subclass(ClippingAttachmentJson::class)
defaultDeserializer { RegionAttachmentJson.serializer() }
}
}
}
fun load(skeletonFile: String, atlasFile: String): EitherFuture {
val link = SkeletonLink(skeletonFile, atlasFile)
return cache.getOrPut(link) {
loadDirect(link)
}
}
fun loadDirect(link:SkeletonLink): EitherFuture {
val atlasLoader = AtlasLoader.load(link.atlasFile)
val spineLoader = resourceLoader.loadText(link.skeletonFile)
val signal = EitherSignal()
spineLoader.thenAccept { rawSpine ->
atlasLoader.thenAccept { atlas ->
val json = JSON.decodeFromString(rawSpine)
val data = SkeletonDecoder(json, link.skeletonFile, atlas).output
signal.accept(SpineData(data, atlas))
}
}
spineLoader.thenReject {
signal.reject(it)
}
atlasLoader.thenReject {
signal.reject(it)
}
return signal
}
}