Более тесно связанные классы ассетов

This commit is contained in:
DBotThePony 2023-02-10 14:55:39 +07:00
parent e01afbefe7
commit ed12e99d43
Signed by: DBot
GPG Key ID: DCC23B5715498507
7 changed files with 48 additions and 36 deletions

View File

@ -161,9 +161,9 @@ class Starbound : ISBFileLocator {
registerTypeAdapter(spriteRegistry) registerTypeAdapter(spriteRegistry)
registerTypeAdapterFactory(InventoryIcon.Factory(pathStack, spriteRegistry)) registerTypeAdapterFactory(InventoryIcon.Factory(pathStack, spriteRegistry))
registerTypeAdapterFactory(IArmorItemDefinition.Frames.Factory(pathStack, this@Starbound::atlasRegistry)) registerTypeAdapterFactory(IArmorItemDefinition.Frames.Factory)
registerTypeAdapterFactory(DirectAssetReferenceFactory(pathStack)) registerTypeAdapterFactory(DirectAssetReferenceFactory(pathStack))
registerTypeAdapter(ImageReference.Adapter(pathStack, this@Starbound::atlasRegistry)) registerTypeAdapterFactory(ImageReference.Adapter(this@Starbound::atlasRegistry))
registerTypeAdapterFactory(AssetReferenceFactory(pathStack, this@Starbound)) registerTypeAdapterFactory(AssetReferenceFactory(pathStack, this@Starbound))

View File

@ -40,7 +40,7 @@ class SpriteAnimator(
animationLoops: Boolean = true, animationLoops: Boolean = true,
firstFrame: Int = 0, firstFrame: Int = 0,
lastFrame: Int = image.config.spriteList.size - 1 lastFrame: Int = image.config.spriteList.size - 1
) : this(state.loadNamedTextureSafe(image.image), image.config, animationCycle, animationLoops, firstFrame, lastFrame) ) : this(state.loadNamedTextureSafe(image.image.fullPath), image.config, animationCycle, animationLoops, firstFrame, lastFrame)
val sprite get() = sprites[frame] val sprite get() = sprites[frame]
} }

View File

@ -185,7 +185,7 @@ private class ModifierEqualityTester(val definition: MaterialModifier) : Equalit
class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) { class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
val state get() = renderers.state val state get() = renderers.state
val texture = state.loadNamedTexture(def.renderParameters.texture.image).also { val texture = state.loadNamedTexture(def.renderParameters.texture.image.fullPath).also {
it.textureMagFilter = GL_NEAREST it.textureMagFilter = GL_NEAREST
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.kstarbound.defs.animation
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import ru.dbotthepony.kstarbound.defs.image.ImageReference
import ru.dbotthepony.kstarbound.defs.image.SpriteReference import ru.dbotthepony.kstarbound.defs.image.SpriteReference
import ru.dbotthepony.kstarbound.defs.particle.ParticleEmitter import ru.dbotthepony.kstarbound.defs.particle.ParticleEmitter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
@ -10,7 +11,13 @@ import ru.dbotthepony.kvector.vector.ndouble.Vector2d
@JsonFactory @JsonFactory
data class AnimationDefinition( data class AnimationDefinition(
val frames: ImageReference? = null,
val animatedParts: AnimatedParts? = null, val animatedParts: AnimatedParts? = null,
val variants: Int? = null,
val frameNumber: Int? = null,
val animationCycle: Double? = null,
val offset: Vector2d? = null,
val sounds: ImmutableMap<String, Either<ImmutableList<String>, CustomSound>> = ImmutableMap.of(), val sounds: ImmutableMap<String, Either<ImmutableList<String>, CustomSound>> = ImmutableMap.of(),
val transformationGroups: ImmutableMap<String, TransformConfig> = ImmutableMap.of(), val transformationGroups: ImmutableMap<String, TransformConfig> = ImmutableMap.of(),
val particleEmitters: ImmutableMap<String, ParticleEmitter> = ImmutableMap.of(), val particleEmitters: ImmutableMap<String, ParticleEmitter> = ImmutableMap.of(),

View File

@ -1,10 +1,14 @@
package ru.dbotthepony.kstarbound.defs.image package ru.dbotthepony.kstarbound.defs.image
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapter import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kstarbound.defs.DirectAssetReference
import ru.dbotthepony.kstarbound.util.PathStack import ru.dbotthepony.kstarbound.util.PathStack
/** /**
@ -13,31 +17,34 @@ import ru.dbotthepony.kstarbound.util.PathStack
* @see [AtlasConfiguration.Companion.get] * @see [AtlasConfiguration.Companion.get]
*/ */
data class ImageReference( data class ImageReference(
val image: String, val image: DirectAssetReference,
val config: AtlasConfiguration, val config: AtlasConfiguration,
) { ) {
class Adapter(private val remapper: PathStack, private val atlasRegistry: () -> AtlasConfiguration.Registry) : TypeAdapter<ImageReference>() { class Adapter(private val atlasRegistry: () -> AtlasConfiguration.Registry) : TypeAdapterFactory {
override fun write(out: JsonWriter, value: ImageReference?) { override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
if (value == null) if (type.rawType == ImageReference::class.java) {
out.nullValue() return object : TypeAdapter<ImageReference>() {
else private val assets = gson.getAdapter(DirectAssetReference::class.java)
out.value(value.image)
}
override fun read(`in`: JsonReader): ImageReference? { override fun write(out: JsonWriter, value: ImageReference?) {
if (`in`.peek() == JsonToken.NULL) out.value(value?.image?.fullPath)
return null }
if (`in`.peek() == JsonToken.STRING) { override fun read(`in`: JsonReader): ImageReference? {
val image = remapper.remap(`in`.nextString()) if (`in`.peek() == JsonToken.NULL)
return null
if (image.contains(':')) val image = assets.read(`in`)
throw JsonSyntaxException("Expected atlas/image reference, but got sprite reference: $image")
return ImageReference(image, atlasRegistry.invoke().get(image)) if (image.path.contains(':'))
throw JsonSyntaxException("Expected atlas/image reference, but got sprite reference: $image")
return ImageReference(image, atlasRegistry.invoke().get(image.fullPath))
}
} as TypeAdapter<T>
} }
throw JsonSyntaxException("Expected atlas/image reference, but got: ${`in`.peek()} near ${`in`.path}") return null
} }
} }
} }

View File

@ -41,7 +41,7 @@ interface IArmorItemDefinition : ILeveledItemDefinition, IScriptableItemDefiniti
override val backSleeve: ImageReference? = null, override val backSleeve: ImageReference? = null,
override val frontSleeve: ImageReference? = null, override val frontSleeve: ImageReference? = null,
) : IFrames { ) : IFrames {
class Factory(private val remapper: PathStack, private val atlasRegistry: () -> AtlasConfiguration.Registry) : TypeAdapterFactory { object Factory : TypeAdapterFactory {
override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? { override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
if (type.rawType == Frames::class.java) { if (type.rawType == Frames::class.java) {
return object : TypeAdapter<Frames>() { return object : TypeAdapter<Frames>() {
@ -52,23 +52,19 @@ interface IArmorItemDefinition : ILeveledItemDefinition, IScriptableItemDefiniti
Frames::frontSleeve, Frames::frontSleeve,
).build(gson) ).build(gson)
private val frames = gson.getAdapter(ImageReference::class.java)
override fun write(out: JsonWriter, value: Frames?) { override fun write(out: JsonWriter, value: Frames?) {
if (value == null) adapter.write(out, value)
out.nullValue()
else
adapter.write(out, value)
} }
override fun read(`in`: JsonReader): Frames? { override fun read(`in`: JsonReader): Frames? {
if (`in`.peek() == JsonToken.NULL) if (`in`.peek() == JsonToken.NULL)
return null return null
else if (`in`.peek() == JsonToken.STRING)
if (`in`.peek() == JsonToken.STRING) { return Frames(frames.read(`in`), null, null)
val path = remapper.remap(`in`.nextString()) else
return Frames(ImageReference(path, atlasRegistry.invoke().get(path)), null, null) return adapter.read(`in`)
}
return adapter.read(`in`)
} }
} as TypeAdapter<T> } as TypeAdapter<T>
} }

View File

@ -14,9 +14,6 @@ import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter import com.google.gson.stream.JsonWriter
class InternedJsonElementAdapter(val stringInterner: Interner<String>) : TypeAdapter<JsonElement>() { class InternedJsonElementAdapter(val stringInterner: Interner<String>) : TypeAdapter<JsonElement>() {
private val _true = JsonPrimitive(true)
private val _false = JsonPrimitive(false)
override fun write(out: JsonWriter, value: JsonElement?) { override fun write(out: JsonWriter, value: JsonElement?) {
return TypeAdapters.JSON_ELEMENT.write(out, value) return TypeAdapters.JSON_ELEMENT.write(out, value)
} }
@ -44,6 +41,11 @@ class InternedJsonElementAdapter(val stringInterner: Interner<String>) : TypeAda
else -> throw IllegalArgumentException(p.toString()) else -> throw IllegalArgumentException(p.toString())
} }
} }
companion object {
private val _true = JsonPrimitive(true)
private val _false = JsonPrimitive(false)
}
} }
class InternedStringAdapter(val stringInterner: Interner<String>) : TypeAdapter<String>() { class InternedStringAdapter(val stringInterner: Interner<String>) : TypeAdapter<String>() {