Все адаптеры на аннотациях

This commit is contained in:
DBotThePony 2023-01-23 13:48:50 +07:00
parent 071e8c4e21
commit f3a2c1d327
Signed by: DBot
GPG Key ID: DCC23B5715498507
12 changed files with 70 additions and 155 deletions

View File

@ -94,7 +94,6 @@ fun addStarboundJsonAdapters(builder: GsonBuilder) {
// Предметы
registerTypeAdapterFactory(IItemDefinition.InventoryIcon.ADAPTER)
registerTypeAdapterFactory(IFossilItemDefinition.FossilSetDescription.ADAPTER)
registerTypeAdapterFactory(IArmorItemDefinition.ArmorFrames.ADAPTER)
// Функции
@ -102,24 +101,9 @@ fun addStarboundJsonAdapters(builder: GsonBuilder) {
registerTypeAdapter(JsonFunction.INTERPOLATION_ADAPTER)
registerTypeAdapter(JsonFunction.Companion)
// Тайлы и жидкости
registerTypeAdapterFactory(MaterialModifier.ADAPTER)
registerTypeAdapterFactory(RenderParameters.ADAPTER)
registerTypeAdapterFactory(RenderPiece.ADAPTER)
registerTypeAdapterFactory(RenderRuleList.ADAPTER)
registerTypeAdapterFactory(RenderMatch.ADAPTER)
registerTypeAdapterFactory(RenderMatch.PIECE_ADAPTER)
registerTypeAdapterFactory(RenderMatch.MATCHER_ADAPTER)
registerTypeAdapterFactory(RenderMatchList.ADAPTER)
registerTypeAdapterFactory(RenderRuleList.Entry.ADAPTER)
registerTypeAdapterFactory(RenderTemplate.ADAPTER)
registerTypeAdapterFactory(TileDefinition.ADAPTER)
registerTypeAdapterFactory(LiquidDefinition.ADAPTER)
registerTypeAdapterFactory(LiquidDefinition.INTERACTION_ADAPTER)
// Общее
registerTypeAdapter(SpriteReference.Companion)
registerTypeAdapter(AtlasConfiguration.ADAPTER)
registerTypeAdapterFactory(AtlasConfiguration.Companion)
registerTypeAdapterFactory(LeveledStatusEffect.ADAPTER)
registerTypeAdapter(MaterialReference.Companion)

View File

@ -2,13 +2,16 @@ package ru.dbotthepony.kstarbound.defs.image
import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.internal.bind.TypeAdapters
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.client.gl.GLTexture2D
@ -152,7 +155,7 @@ class AtlasConfiguration private constructor(
}
}
companion object {
companion object : TypeAdapterFactory {
val EMPTY: AtlasConfiguration
init {
@ -304,6 +307,12 @@ class AtlasConfiguration private constructor(
return EMPTY
}
val ADAPTER: TypeAdapter<AtlasConfiguration?> = Starbound.NULLABLE_STRING_ADAPTER.transform(read = read@{ get(it ?: return@read it as AtlasConfiguration?) }, write = write@{ it?.name })
override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
if (type.rawType == AtlasConfiguration::class.java) {
return gson.getAdapter(String::class.java).transform(read = read@{ get(it ?: return@read it as AtlasConfiguration?) }, write = write@{ it?.name }) as TypeAdapter<T>
}
return null
}
}
}

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.kstarbound.defs.item
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonImplementation
import ru.dbotthepony.kstarbound.io.json.ifString
interface IArmorItemDefinition : ILeveledItemDefinition, IScriptableItemDefinition {
@ -25,6 +26,7 @@ interface IArmorItemDefinition : ILeveledItemDefinition, IScriptableItemDefiniti
*/
val femaleFrames: IArmorFrames
@JsonImplementation(ArmorFrames::class)
interface IArmorFrames {
val body: String
val backSleeve: String?

View File

@ -2,6 +2,8 @@ package ru.dbotthepony.kstarbound.defs.item
import ru.dbotthepony.kstarbound.defs.IThingWithDescription
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.io.json.builder.JsonImplementation
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
interface IFossilItemDefinition : IItemDefinition {
@ -47,6 +49,7 @@ interface IFossilItemDefinition : IItemDefinition {
*/
val completeSetDescriptions: IFossilSetDescription?
@JsonImplementation(FossilSetDescription::class)
interface IFossilSetDescription : IThingWithDescription {
/**
* Цена в пикселях
@ -54,17 +57,10 @@ interface IFossilItemDefinition : IItemDefinition {
val price: Long
}
@JsonFactory
data class FossilSetDescription(
override val price: Long = 0L,
override val shortdescription: String = "...",
override val description: String = "..."
) : IFossilSetDescription {
companion object {
val ADAPTER = FactoryAdapter.Builder(
FossilSetDescription::class,
FossilSetDescription::price,
FossilSetDescription::shortdescription,
FossilSetDescription::description)
}
}
) : IFossilSetDescription
}

View File

@ -3,9 +3,11 @@ package ru.dbotthepony.kstarbound.defs.liquid
import com.google.common.collect.ImmutableList
import com.google.gson.GsonBuilder
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.registerTypeAdapter
import ru.dbotthepony.kvector.vector.Color
@JsonFactory
data class LiquidDefinition(
val name: String,
val liquidId: Int,
@ -19,33 +21,10 @@ data class LiquidDefinition(
val bottomLightMix: Color,
val textureMovementFactor: Double,
) {
@JsonFactory
data class Interaction(val liquid: Int, val liquidResult: Int? = null, val materialResult: String? = null) {
init {
require(liquidResult != null || materialResult != null) { "Both liquidResult and materialResult are missing" }
}
}
companion object {
val ADAPTER = FactoryAdapter.Builder(LiquidDefinition::class)
.auto(LiquidDefinition::name)
.auto(LiquidDefinition::liquidId)
.auto(LiquidDefinition::description)
.auto(LiquidDefinition::tickDelta)
.auto(LiquidDefinition::color)
.auto(LiquidDefinition::itemDrop)
.auto(LiquidDefinition::statusEffects)
.auto(LiquidDefinition::interactions)
.auto(LiquidDefinition::texture)
.auto(LiquidDefinition::bottomLightMix)
.auto(LiquidDefinition::textureMovementFactor)
val INTERACTION_ADAPTER = FactoryAdapter.Builder(Interaction::class)
.auto(Interaction::liquid)
.auto(Interaction::liquidResult)
.auto(Interaction::materialResult)
fun registerGson(gsonBuilder: GsonBuilder) {
}
}
}

View File

@ -3,7 +3,9 @@ package ru.dbotthepony.kstarbound.defs.tile
import com.google.common.collect.ImmutableList
import com.google.gson.GsonBuilder
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
@JsonFactory
data class MaterialModifier(
val modId: Int,
val modName: String,
@ -21,20 +23,4 @@ data class MaterialModifier(
init {
require(modId > 0) { "Invalid material modifier ID $modId" }
}
companion object {
val ADAPTER = FactoryAdapter.Builder(MaterialModifier::class)
.auto(MaterialModifier::modId)
.auto(MaterialModifier::modName)
.auto(MaterialModifier::itemDrop)
.auto(MaterialModifier::description)
.auto(MaterialModifier::health)
.auto(MaterialModifier::harvestLevel)
.auto(MaterialModifier::breaksWithTile)
.auto(MaterialModifier::grass)
.auto(MaterialModifier::miningSounds)
.auto(MaterialModifier::miningParticle)
.auto(MaterialModifier::renderTemplate)
.auto(MaterialModifier::renderParameters)
}
}

View File

@ -3,9 +3,11 @@ package ru.dbotthepony.kstarbound.defs.tile
import com.google.gson.GsonBuilder
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
const val TILE_COLOR_VARIANTS = 9
@JsonFactory
data class RenderParameters(
val texture: String,
val variants: Int = 0,
@ -25,14 +27,4 @@ data class RenderParameters(
absoluteTexturePath = "$dir/$texture"
}
}
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderParameters::class)
.auto(RenderParameters::texture)
.auto(RenderParameters::variants)
.auto(RenderParameters::multiColored)
.auto(RenderParameters::occludesBelow)
.auto(RenderParameters::lightTransparent)
.auto(RenderParameters::zLevel)
}
}

View File

@ -9,10 +9,12 @@ import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import it.unimi.dsi.fastutil.objects.ObjectArraySet
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.io.json.builder.EnumAdapter
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.io.json.util.asReference
import ru.dbotthepony.kstarbound.registerTypeAdapter
import ru.dbotthepony.kstarbound.util.WriteOnce
@ -21,27 +23,20 @@ import ru.dbotthepony.kstarbound.world.ITileState
import ru.dbotthepony.kvector.vector.nint.Vector2i
import java.util.concurrent.ConcurrentHashMap
@JsonFactory
data class RenderPiece(
val texture: String? = null,
val textureSize: Vector2i,
val texturePosition: Vector2i,
val colorStride: Vector2i? = null,
val variantStride: Vector2i? = null,
) {
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderPiece::class)
.auto(RenderPiece::texture)
.auto(RenderPiece::textureSize)
.auto(RenderPiece::texturePosition)
.auto(RenderPiece::colorStride)
.auto(RenderPiece::variantStride)
}
}
)
fun interface EqualityRuleTester {
fun test(thisTile: ITileState, otherTile: ITileState): Boolean
}
@JsonFactory
data class RenderRuleList(
val entries: ImmutableList<Entry>,
val join: Combination = Combination.ALL
@ -50,6 +45,7 @@ data class RenderRuleList(
ALL, ANY;
}
@JsonFactory
data class Entry(
val type: String,
val matchHue: Boolean = false,
@ -80,12 +76,7 @@ data class RenderRuleList(
companion object {
private val LOGGER = LogManager.getLogger()
private val LOGGED = ObjectArraySet<String>()
val ADAPTER = FactoryAdapter.Builder(Entry::class)
.auto(Entry::type)
.auto(Entry::matchHue)
.auto(Entry::inverse)
private val LOGGED = ObjectOpenHashSet<String>()
}
}
@ -112,14 +103,9 @@ data class RenderRuleList(
}
}
}
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderRuleList::class)
.auto(RenderRuleList::entries)
.auto(RenderRuleList::join)
}
}
@JsonFactory
data class RenderMatch(
val pieces: ImmutableList<Piece> = ImmutableList.of(),
val matchAllPoints: ImmutableList<Matcher> = ImmutableList.of(),
@ -128,6 +114,7 @@ data class RenderMatch(
val haltOnMatch: Boolean = false,
val haltOnSubMatch: Boolean = false,
) {
@JsonFactory(asList = true)
data class Piece(
val name: String,
val offset: Vector2i
@ -139,6 +126,7 @@ data class RenderMatch(
}
}
@JsonFactory(asList = true)
data class Matcher(
val offset: Vector2i,
val ruleName: String
@ -200,28 +188,9 @@ data class RenderMatch(
return false
}
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderMatch::class)
.auto(RenderMatch::pieces)
.auto(RenderMatch::matchAllPoints)
.auto(RenderMatch::matchAnyPoints)
.auto(RenderMatch::subMatches)
.auto(RenderMatch::haltOnMatch)
.auto(RenderMatch::haltOnSubMatch)
val PIECE_ADAPTER = FactoryAdapter.Builder(Piece::class)
.auto(Piece::name)
.auto(Piece::offset)
.inputAsList()
val MATCHER_ADAPTER = FactoryAdapter.Builder(Matcher::class)
.auto(Matcher::offset)
.auto(Matcher::ruleName)
.inputAsList()
}
}
@JsonFactory(asList = true)
data class RenderMatchList(
val name: String,
val list: ImmutableList<RenderMatch>
@ -231,15 +200,9 @@ data class RenderMatchList(
value.resolve(template)
}
}
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderMatchList::class)
.auto(RenderMatchList::name)
.auto(RenderMatchList::list)
.inputAsList()
}
}
@JsonFactory(asReference = true)
data class RenderTemplate(
val pieces: ImmutableMap<String, RenderPiece>,
val representativePiece: String,
@ -251,13 +214,4 @@ data class RenderTemplate(
value.resolve(this)
}
}
companion object {
val ADAPTER = FactoryAdapter.Builder(RenderTemplate::class)
.auto(RenderTemplate::pieces)
.auto(RenderTemplate::representativePiece)
.auto(RenderTemplate::matches)
.auto(RenderTemplate::rules)
.asReference()
}
}

View File

@ -2,9 +2,11 @@ package ru.dbotthepony.kstarbound.defs.tile
import com.google.gson.GsonBuilder
import ru.dbotthepony.kstarbound.io.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.io.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.registerTypeAdapter
import ru.dbotthepony.kvector.vector.Color
@JsonFactory
data class TileDefinition(
val materialId: Int,
val materialName: String,
@ -22,21 +24,4 @@ data class TileDefinition(
override val renderTemplate: RenderTemplate,
override val renderParameters: RenderParameters,
) : IRenderableTile {
companion object {
val ADAPTER = FactoryAdapter.Builder(TileDefinition::class)
.auto(TileDefinition::materialId)
.auto(TileDefinition::materialName)
.auto(TileDefinition::particleColor)
.auto(TileDefinition::itemDrop)
.auto(TileDefinition::description)
.auto(TileDefinition::shortdescription)
.auto(TileDefinition::footstepSound)
.auto(TileDefinition::blocksLiquidFlow)
.auto(TileDefinition::soil)
.auto(TileDefinition::health)
.auto(TileDefinition::category)
.auto(TileDefinition::renderTemplate)
.auto(TileDefinition::renderParameters)
}
}
) : IRenderableTile

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.kstarbound.io.json.builder
import ru.dbotthepony.kstarbound.io.json.util.ReferenceAdapter
import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
@ -37,7 +38,15 @@ annotation class JsonBuilder(
*/
val logMisses: Int = 0,
/**
* Включать ли свойства родительского класса в данный [BuilderAdapter]
*/
val includeSuperclassProperties: Boolean = true,
/**
* Оборачивает созданный [BuilderAdapter] в [ReferenceAdapter]
*/
val asReference: Boolean = false,
)
val JsonBuilder.realLogMisses get() = logMisses.toBool()
@ -92,7 +101,12 @@ annotation class JsonFactory(
* @see FactoryAdapter.Builder.inputAsList
* @see FactoryAdapter.Builder.inputAsMap
*/
val asList: Boolean = false
val asList: Boolean = false,
/**
* Оборачивает созданный [FactoryAdapter] в [ReferenceAdapter]
*/
val asReference: Boolean = false,
)
/**

View File

@ -18,6 +18,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.util.flattenJsonElement
import ru.dbotthepony.kstarbound.io.json.util.asReference
import ru.dbotthepony.kstarbound.util.NotNullVar
import kotlin.properties.Delegates
import kotlin.reflect.KCallable
@ -378,6 +379,10 @@ class BuilderAdapter<T : Any> private constructor(
builder.logMisses = bconfig.realLogMisses
builder.extraPropertiesAreFatal = bconfig.extraPropertiesAreFatal
for (name in bconfig.ignoreKeys) {
builder.ignoreKey(name)
}
val declarations = LinkedHashMap<String, KMutableProperty1<*, *>>()
collectDecl(kclass, declarations)
@ -394,6 +399,10 @@ class BuilderAdapter<T : Any> private constructor(
}
}
if (bconfig.asReference) {
return builder.build(gson).asReference()
}
return builder.build(gson)
}

View File

@ -28,6 +28,7 @@ import ru.dbotthepony.kstarbound.io.json.util.LazyTypeProvider
import ru.dbotthepony.kstarbound.io.json.util.ListAdapter
import ru.dbotthepony.kstarbound.io.json.util.MapAdapter
import ru.dbotthepony.kstarbound.io.json.util.String2ObjectAdapter
import ru.dbotthepony.kstarbound.io.json.util.asReference
import ru.dbotthepony.kstarbound.setValue
import java.lang.reflect.Constructor
import kotlin.jvm.internal.DefaultConstructorMarker
@ -571,6 +572,10 @@ class FactoryAdapter<T : Any> private constructor(
}
}
if (bconfig.asReference) {
return builder.build(gson).asReference()
}
return builder.build(gson)
}