All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.spine.json.JsonSkeletonLoader.kt Maven / Gradle / Ivy

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
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy