From c80372e0fa6df6fc5d6a7854a1453219a0c57d62 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 22 Jan 2023 23:11:15 +0700 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=D0=B0=20=D0=BD=D0=B0=20Typ?= =?UTF-8?q?eAdapterFactory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/dbotthepony/kstarbound/Starbound.kt | 45 +----- .../kstarbound/StarboundJsonAdapters.kt | 144 ++++++++++++++++++ .../kstarbound/client/render/TileRenderer.kt | 1 + .../kstarbound/defs/JsonFunction.kt | 23 +-- .../defs/image/AtlasConfiguration.kt | 4 - .../kstarbound/defs/image/SpriteReference.kt | 4 - .../defs/item/IArmorItemDefinition.kt | 4 +- .../defs/item/IFossilItemDefinition.kt | 2 +- .../kstarbound/defs/item/IItemDefinition.kt | 2 +- .../defs/liquid/LiquidDefinition.kt | 3 +- .../defs/parallax/ParallaxPrototype.kt | 9 -- .../defs/projectile/Configurable.kt | 31 +--- .../kstarbound/defs/tile/MaterialModifier.kt | 4 - .../kstarbound/defs/tile/RenderParameters.kt | 4 - .../kstarbound/defs/tile/RenderTemplate.kt | 17 --- .../kstarbound/defs/tile/TileDefinition.kt | 4 - .../kstarbound/defs/world/SkyParameters.kt | 16 +- .../defs/world/dungeon/Configurable.kt | 6 - .../io/json/ContextualizedTypeAdapter.kt | 47 ++++++ .../ru/dbotthepony/kstarbound/io/json/Ext.kt | 12 ++ .../io/json/builder/BuilderAdapter.kt | 8 +- .../io/json/builder/FactoryAdapter.kt | 25 ++- 22 files changed, 247 insertions(+), 168 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/io/json/ContextualizedTypeAdapter.kt diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt index 1ec99501..0d9c63b3 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt @@ -41,7 +41,6 @@ import ru.dbotthepony.kstarbound.defs.world.dungeon.DungeonWorldDef import ru.dbotthepony.kstarbound.io.* import ru.dbotthepony.kstarbound.io.json.AABBTypeAdapter import ru.dbotthepony.kstarbound.io.json.AABBiTypeAdapter -import ru.dbotthepony.kstarbound.io.json.MappedTypeFactories import ru.dbotthepony.kstarbound.io.json.builder.EnumAdapter import ru.dbotthepony.kstarbound.io.json.Vector2dTypeAdapter import ru.dbotthepony.kstarbound.io.json.Vector2fTypeAdapter @@ -49,7 +48,6 @@ import ru.dbotthepony.kstarbound.io.json.Vector2iTypeAdapter import ru.dbotthepony.kstarbound.io.json.Vector4iTypeAdapter import ru.dbotthepony.kstarbound.io.json.factory.ImmutableCollectionAdapterFactory import ru.dbotthepony.kstarbound.math.* -import ru.dbotthepony.kvector.vector.Color import java.io.* import java.text.DateFormat import java.util.* @@ -147,52 +145,11 @@ object Starbound { .setDateFormat(DateFormat.LONG) .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) .setPrettyPrinting() - .registerTypeAdapter(ColorTypeAdapter.nullSafe()) - - .registerTypeAdapterFactory(ImmutableCollectionAdapterFactory) // чтоб строки всегда intern'ились .registerTypeAdapter(NULLABLE_STRING_ADAPTER) - // math - .registerTypeAdapter(AABBTypeAdapter) - .registerTypeAdapter(AABBiTypeAdapter) - .registerTypeAdapter(Vector2dTypeAdapter) - .registerTypeAdapter(Vector2fTypeAdapter) - .registerTypeAdapter(Vector2iTypeAdapter) - .registerTypeAdapter(Vector4iTypeAdapter) - .registerTypeAdapter(PolyTypeAdapter) - - .also(ConfigurableProjectile::registerGson) - .also(SkyParameters::registerGson) - .also(DungeonWorldDef::registerGson) - .also(ParallaxPrototype::registerGson) - .also(JsonFunction::registerGson) - .also(MaterialModifier::registerGson) - .also(RenderParameters::registerGson) - .also(RenderTemplate::registerGson) - .also(TileDefinition::registerGson) - .also(LiquidDefinition::registerGson) - .also(SpriteReference::registerGson) - .also(AtlasConfiguration::registerGson) - - .registerTypeAdapterFactory(LeveledStatusEffect.ADAPTER) - .registerTypeAdapter(MaterialReference.Companion) - .registerTypeAdapter(ThingDescription.Companion) - - .registerTypeAdapterFactory(ItemPrototype.ADAPTER) - .registerTypeAdapterFactory(CurrencyItemPrototype.ADAPTER) - .registerTypeAdapterFactory(ArmorItemPrototype.ADAPTER) - .registerTypeAdapterFactory(MaterialItemPrototype.ADAPTER) - .registerTypeAdapterFactory(LiquidItemPrototype.ADAPTER) - - .registerTypeAdapter(IItemDefinition.InventoryIcon.ADAPTER) - .registerTypeAdapter(IFossilItemDefinition.FossilSetDescription.ADAPTER) - .registerTypeAdapter(IArmorItemDefinition.ArmorFrames.ADAPTER) - - .registerTypeAdapter(EnumAdapter(DamageType::class, default = DamageType.NORMAL).neverNull()) - .registerTypeAdapter(EnumAdapter(ItemRarity::class).neverNull()) - .registerTypeAdapter(EnumAdapter(ItemTooltipKind::class).neverNull()) + .also(::addStarboundJsonAdapters) .create() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt new file mode 100644 index 00000000..fd392719 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt @@ -0,0 +1,144 @@ +package ru.dbotthepony.kstarbound + +import com.google.gson.GsonBuilder +import ru.dbotthepony.kstarbound.defs.DamageType +import ru.dbotthepony.kstarbound.defs.JsonFunction +import ru.dbotthepony.kstarbound.defs.MaterialReference +import ru.dbotthepony.kstarbound.defs.ThingDescription +import ru.dbotthepony.kstarbound.defs.image.AtlasConfiguration +import ru.dbotthepony.kstarbound.defs.image.SpriteReference +import ru.dbotthepony.kstarbound.defs.item.ArmorItemPrototype +import ru.dbotthepony.kstarbound.defs.item.CurrencyItemPrototype +import ru.dbotthepony.kstarbound.defs.item.IArmorItemDefinition +import ru.dbotthepony.kstarbound.defs.item.IFossilItemDefinition +import ru.dbotthepony.kstarbound.defs.item.IItemDefinition +import ru.dbotthepony.kstarbound.defs.item.ItemPrototype +import ru.dbotthepony.kstarbound.defs.item.ItemRarity +import ru.dbotthepony.kstarbound.defs.item.ItemTooltipKind +import ru.dbotthepony.kstarbound.defs.item.LeveledStatusEffect +import ru.dbotthepony.kstarbound.defs.item.LiquidItemPrototype +import ru.dbotthepony.kstarbound.defs.item.MaterialItemPrototype +import ru.dbotthepony.kstarbound.defs.liquid.LiquidDefinition +import ru.dbotthepony.kstarbound.defs.parallax.ParallaxPrototype +import ru.dbotthepony.kstarbound.defs.parallax.ParallaxPrototypeLayer +import ru.dbotthepony.kstarbound.defs.projectile.ActionActions +import ru.dbotthepony.kstarbound.defs.projectile.ActionConfig +import ru.dbotthepony.kstarbound.defs.projectile.ActionLoop +import ru.dbotthepony.kstarbound.defs.projectile.ActionProjectile +import ru.dbotthepony.kstarbound.defs.projectile.ActionSound +import ru.dbotthepony.kstarbound.defs.projectile.ConfigurableProjectile +import ru.dbotthepony.kstarbound.defs.projectile.ProjectilePhysics +import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier +import ru.dbotthepony.kstarbound.defs.tile.RenderMatch +import ru.dbotthepony.kstarbound.defs.tile.RenderMatchList +import ru.dbotthepony.kstarbound.defs.tile.RenderParameters +import ru.dbotthepony.kstarbound.defs.tile.RenderPiece +import ru.dbotthepony.kstarbound.defs.tile.RenderRuleList +import ru.dbotthepony.kstarbound.defs.tile.RenderTemplate +import ru.dbotthepony.kstarbound.defs.tile.TileDefinition +import ru.dbotthepony.kstarbound.defs.world.SkyColoring +import ru.dbotthepony.kstarbound.defs.world.SkyColoringManifold +import ru.dbotthepony.kstarbound.defs.world.SkyParameters +import ru.dbotthepony.kstarbound.defs.world.SkySatellite +import ru.dbotthepony.kstarbound.defs.world.SkyType +import ru.dbotthepony.kstarbound.defs.world.dungeon.BeamUpRule +import ru.dbotthepony.kstarbound.defs.world.dungeon.DungeonType +import ru.dbotthepony.kstarbound.defs.world.dungeon.DungeonWorldDef +import ru.dbotthepony.kstarbound.io.ColorTypeAdapter +import ru.dbotthepony.kstarbound.io.json.AABBTypeAdapter +import ru.dbotthepony.kstarbound.io.json.AABBiTypeAdapter +import ru.dbotthepony.kstarbound.io.json.Vector2dTypeAdapter +import ru.dbotthepony.kstarbound.io.json.Vector2fTypeAdapter +import ru.dbotthepony.kstarbound.io.json.Vector2iTypeAdapter +import ru.dbotthepony.kstarbound.io.json.Vector4iTypeAdapter +import ru.dbotthepony.kstarbound.io.json.builder.EnumAdapter +import ru.dbotthepony.kstarbound.io.json.factory.ImmutableCollectionAdapterFactory +import ru.dbotthepony.kstarbound.math.PolyTypeAdapter + +fun addStarboundJsonAdapters(builder: GsonBuilder) { + with(builder) { + // ImmutableList, и прочее + registerTypeAdapterFactory(ImmutableCollectionAdapterFactory) + + registerTypeAdapter(ColorTypeAdapter.nullSafe()) + + // математические классы + registerTypeAdapter(AABBTypeAdapter) + registerTypeAdapter(AABBiTypeAdapter) + registerTypeAdapter(Vector2dTypeAdapter) + registerTypeAdapter(Vector2fTypeAdapter) + registerTypeAdapter(Vector2iTypeAdapter) + registerTypeAdapter(Vector4iTypeAdapter) + registerTypeAdapter(PolyTypeAdapter) + + // Снаряды + registerTypeAdapterFactory(ConfigurableProjectile.ADAPTER) + registerTypeAdapter(EnumAdapter(ProjectilePhysics::class).neverNull()) + registerTypeAdapterFactory(ActionConfig.ADAPTER) + registerTypeAdapterFactory(ActionProjectile.ADAPTER) + registerTypeAdapterFactory(ActionSound.ADAPTER) + registerTypeAdapterFactory(ActionLoop.ADAPTER) + registerTypeAdapterFactory(ActionActions.ADAPTER) + + // Параметры неба + registerTypeAdapterFactory(SkyParameters.ADAPTER) + registerTypeAdapter(SkyColoringManifold.ADAPTER) + registerTypeAdapterFactory(SkyColoring.ADAPTER) + registerTypeAdapter(EnumAdapter(SkyType::class)) + registerTypeAdapterFactory(SkySatellite.ADAPTER) + registerTypeAdapterFactory(SkySatellite.LAYER_ADAPTER) + + // Данные о данжах + registerTypeAdapterFactory(DungeonWorldDef.ADAPTER) + registerTypeAdapter(EnumAdapter(BeamUpRule::class)) + registerTypeAdapter(EnumAdapter(DungeonType::class)) + + // Параллакс + registerTypeAdapterFactory(ParallaxPrototype.ADAPTER) + registerTypeAdapterFactory(ParallaxPrototypeLayer.ADAPTER) + registerTypeAdapter(ParallaxPrototypeLayer.LAYER_PARALLAX_ADAPTER) + + // Предметы + registerTypeAdapterFactory(ItemPrototype.ADAPTER) + registerTypeAdapterFactory(CurrencyItemPrototype.ADAPTER) + registerTypeAdapterFactory(ArmorItemPrototype.ADAPTER) + registerTypeAdapterFactory(MaterialItemPrototype.ADAPTER) + registerTypeAdapterFactory(LiquidItemPrototype.ADAPTER) + registerTypeAdapterFactory(IItemDefinition.InventoryIcon.ADAPTER) + registerTypeAdapterFactory(IFossilItemDefinition.FossilSetDescription.ADAPTER) + registerTypeAdapterFactory(IArmorItemDefinition.ArmorFrames.ADAPTER) + + // Функции + registerTypeAdapter(JsonFunction.CONSTRAINT_ADAPTER) + 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) + registerTypeAdapter(EnumAdapter(RenderRuleList.Combination::class)) + registerTypeAdapterFactory(TileDefinition.ADAPTER) + registerTypeAdapterFactory(LiquidDefinition.ADAPTER) + registerTypeAdapterFactory(LiquidDefinition.INTERACTION_ADAPTER) + + // Общее + registerTypeAdapter(SpriteReference.Companion) + registerTypeAdapter(AtlasConfiguration.ADAPTER) + + registerTypeAdapterFactory(LeveledStatusEffect.ADAPTER) + registerTypeAdapter(MaterialReference.Companion) + registerTypeAdapter(ThingDescription.Companion) + + registerTypeAdapter(EnumAdapter(DamageType::class, default = DamageType.NORMAL)) + registerTypeAdapter(EnumAdapter(ItemRarity::class)) + registerTypeAdapter(EnumAdapter(ItemTooltipKind::class)) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/TileRenderer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/TileRenderer.kt index 8f2e6976..19944e58 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/TileRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/TileRenderer.kt @@ -190,6 +190,7 @@ class TileRenderer(val state: GLStateTracker, val def: IRenderableTile) { val equalityTester: EqualityRuleTester = when (def) { is TileDefinition -> TileEqualityTester(def) is MaterialModifier -> ModifierEqualityTester(def) + else -> throw IllegalStateException() } val bakedProgramState = state.tileRenderers.foreground(texture) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/JsonFunction.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/JsonFunction.kt index a3a24f01..b9e2b00c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/JsonFunction.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/JsonFunction.kt @@ -1,7 +1,7 @@ package ru.dbotthepony.kstarbound.defs import com.google.common.collect.ImmutableList -import com.google.gson.GsonBuilder +import com.google.gson.JsonSyntaxException import com.google.gson.TypeAdapter import com.google.gson.stream.JsonReader import com.google.gson.stream.JsonToken @@ -27,10 +27,6 @@ enum class JsonFunctionInterpolation(vararg aliases: String) : IStringSerializab override fun write(out: JsonWriter) { out.value(this.name) } - - companion object { - val ADAPTER: TypeAdapter = EnumAdapter(JsonFunctionInterpolation::class).neverNull() - } } enum class JsonFunctionConstraint(vararg aliases: String) : IStringSerializable { @@ -49,10 +45,6 @@ enum class JsonFunctionConstraint(vararg aliases: String) : IStringSerializable override fun write(out: JsonWriter) { out.value(this.name) } - - companion object { - val ADAPTER: TypeAdapter = EnumAdapter(JsonFunctionConstraint::class).neverNull() - } } class JsonFunction( @@ -61,6 +53,9 @@ class JsonFunction( val ranges: List ) { companion object : TypeAdapter() { + val CONSTRAINT_ADAPTER = EnumAdapter(JsonFunctionConstraint::class) + val INTERPOLATION_ADAPTER = EnumAdapter(JsonFunctionInterpolation::class) + override fun write(out: JsonWriter, value: JsonFunction) { TODO("Not yet implemented") } @@ -68,8 +63,8 @@ class JsonFunction( override fun read(reader: JsonReader): JsonFunction { reader.beginArray() - val interpolation = JsonFunctionInterpolation.ADAPTER.read(reader) - val constraint = JsonFunctionConstraint.ADAPTER.read(reader) + val interpolation = INTERPOLATION_ADAPTER.read(reader) ?: throw JsonSyntaxException("Missing interpolation") + val constraint = CONSTRAINT_ADAPTER.read(reader) ?: throw JsonSyntaxException("Missing constraint") val ranges = ArrayList() @@ -81,11 +76,5 @@ class JsonFunction( return JsonFunction(interpolation, constraint, ImmutableList.copyOf(ranges)) } - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(JsonFunctionConstraint::class.java, JsonFunctionConstraint.ADAPTER) - gsonBuilder.registerTypeAdapter(JsonFunctionInterpolation::class.java, JsonFunctionInterpolation.ADAPTER) - gsonBuilder.registerTypeAdapter(JsonFunction::class.java, this) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/AtlasConfiguration.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/AtlasConfiguration.kt index e1e1308f..af1cb532 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/AtlasConfiguration.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/AtlasConfiguration.kt @@ -305,9 +305,5 @@ class AtlasConfiguration private constructor( } val ADAPTER: TypeAdapter = Starbound.NULLABLE_STRING_ADAPTER.transform(read = read@{ get(it ?: return@read it as AtlasConfiguration?) }, write = write@{ it?.name }) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(ADAPTER) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/SpriteReference.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/SpriteReference.kt index 9e55ec30..455d1277 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/SpriteReference.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/image/SpriteReference.kt @@ -32,9 +32,5 @@ data class SpriteReference( override fun read(`in`: JsonReader): SpriteReference { return parse(Starbound.assetFolder(`in`.nextString())) } - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(this) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IArmorItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IArmorItemDefinition.kt index db9d9da0..247c90ae 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IArmorItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IArmorItemDefinition.kt @@ -42,9 +42,7 @@ interface IArmorItemDefinition : ILeveledItemDefinition, IScriptableItemDefiniti ArmorFrames::body, ArmorFrames::backSleeve, ArmorFrames::frontSleeve, - ) - .build() - .ifString { ArmorFrames(Starbound.assetFolder(it), null, null) } + ).ifString { ArmorFrames(Starbound.assetFolder(it), null, null) } } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IFossilItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IFossilItemDefinition.kt index 9284e6e7..d6d3ffa0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IFossilItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IFossilItemDefinition.kt @@ -64,7 +64,7 @@ interface IFossilItemDefinition : IItemDefinition { FossilSetDescription::class, FossilSetDescription::price, FossilSetDescription::shortdescription, - FossilSetDescription::description).build() + FossilSetDescription::description) } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IItemDefinition.kt index 436e1df6..b77ef64e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/IItemDefinition.kt @@ -44,7 +44,7 @@ interface IItemDefinition : IThingWithDescription { override val image: SpriteReference ) : IInventoryIcon { companion object { - val ADAPTER = FactoryAdapter.Builder(InventoryIcon::class, InventoryIcon::image).build().ifString { InventoryIcon(SpriteReference.parse(Starbound.assetFolder(it))) } + val ADAPTER = FactoryAdapter.Builder(InventoryIcon::class, InventoryIcon::image).ifString { InventoryIcon(SpriteReference.parse(Starbound.assetFolder(it))) } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/liquid/LiquidDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/liquid/LiquidDefinition.kt index a33178ed..77b78746 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/liquid/LiquidDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/liquid/LiquidDefinition.kt @@ -45,8 +45,7 @@ data class LiquidDefinition( .auto(Interaction::materialResult) fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapterFactory(ADAPTER) - gsonBuilder.registerTypeAdapterFactory(INTERACTION_ADAPTER) + } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/parallax/ParallaxPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/parallax/ParallaxPrototype.kt index 92b0d3ea..a18afe22 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/parallax/ParallaxPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/parallax/ParallaxPrototype.kt @@ -14,14 +14,5 @@ class ParallaxPrototype { ParallaxPrototype::verticalOrigin, ParallaxPrototype::layers, ) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(ParallaxPrototype::class.java, ADAPTER) - gsonBuilder.registerTypeAdapter(ParallaxPrototypeLayer::class.java, ParallaxPrototypeLayer.ADAPTER) - gsonBuilder.registerTypeAdapter( - ParallaxPrototypeLayer.Parallax::class.java, - ParallaxPrototypeLayer.LAYER_PARALLAX_ADAPTER - ) - } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/projectile/Configurable.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/projectile/Configurable.kt index 0b9919e6..f3b59b0e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/projectile/Configurable.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/projectile/Configurable.kt @@ -120,16 +120,6 @@ class ConfigurableProjectile : RawPrototype() } @@ -204,11 +194,7 @@ class ActionProjectile : IConfigurableAction { } companion object { - val ADAPTER = BuilderAdapter.Builder(::ActionProjectile, - ActionProjectile::type, - ActionProjectile::angle, - ActionProjectile::inheritDamageFactor, - ).ignoreKey("action").build() + val ADAPTER = BuilderAdapter.Builder(::ActionProjectile, ActionProjectile::type, ActionProjectile::angle, ActionProjectile::inheritDamageFactor).ignoreKey("action") } } @@ -223,9 +209,7 @@ class ActionSound : IConfigurableAction { } companion object { - val ADAPTER = BuilderAdapter.Builder(::ActionSound, - ActionSound::options, - ).ignoreKey("action").build() + val ADAPTER = BuilderAdapter.Builder(::ActionSound, ActionSound::options).ignoreKey("action") } } @@ -241,10 +225,7 @@ class ActionLoop : IConfigurableAction { } companion object { - val ADAPTER = BuilderAdapter.Builder(::ActionLoop, - ActionLoop::count, - ActionLoop::body, - ).ignoreKey("action").build() + val ADAPTER = BuilderAdapter.Builder(::ActionLoop, ActionLoop::count, ActionLoop::body).ignoreKey("action") } } @@ -259,8 +240,6 @@ class ActionActions : IConfigurableAction { } companion object { - val ADAPTER = BuilderAdapter.Builder(::ActionActions, - ActionActions::list, - ).ignoreKey("action").build() + val ADAPTER = BuilderAdapter.Builder(::ActionActions, ActionActions::list).ignoreKey("action") } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/MaterialModifier.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/MaterialModifier.kt index 02a2f62a..aee1d067 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/MaterialModifier.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/MaterialModifier.kt @@ -36,9 +36,5 @@ data class MaterialModifier( .auto(MaterialModifier::miningParticle) .auto(MaterialModifier::renderTemplate) .auto(MaterialModifier::renderParameters) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapterFactory(ADAPTER) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderParameters.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderParameters.kt index 04ba8d05..1e863f76 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderParameters.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderParameters.kt @@ -34,9 +34,5 @@ data class RenderParameters( .auto(RenderParameters::occludesBelow) .auto(RenderParameters::lightTransparent) .auto(RenderParameters::zLevel) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapterFactory(ADAPTER) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderTemplate.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderTemplate.kt index 203e8ad6..614405de 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderTemplate.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/RenderTemplate.kt @@ -86,7 +86,6 @@ data class RenderRuleList( .auto(Entry::type) .auto(Entry::matchHue) .auto(Entry::inverse) - .build() } } @@ -118,7 +117,6 @@ data class RenderRuleList( val ADAPTER = FactoryAdapter.Builder(RenderRuleList::class) .auto(RenderRuleList::entries) .auto(RenderRuleList::join) - .build() } } @@ -261,20 +259,5 @@ data class RenderTemplate( .auto(RenderTemplate::matches) .auto(RenderTemplate::rules) .asReference() - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapterFactory(RenderPiece.ADAPTER) - gsonBuilder.registerTypeAdapter(RenderRuleList.ADAPTER) - gsonBuilder.registerTypeAdapterFactory(RenderMatch.ADAPTER) - gsonBuilder.registerTypeAdapterFactory(RenderMatch.PIECE_ADAPTER) - gsonBuilder.registerTypeAdapterFactory(RenderMatch.MATCHER_ADAPTER) - gsonBuilder.registerTypeAdapterFactory(RenderMatchList.ADAPTER) - - gsonBuilder.registerTypeAdapter(RenderRuleList.Entry.ADAPTER) - - gsonBuilder.registerTypeAdapterFactory(ADAPTER) - - gsonBuilder.registerTypeAdapter(EnumAdapter(RenderRuleList.Combination::class.java)) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/TileDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/TileDefinition.kt index a3228a53..a857474d 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/TileDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/tile/TileDefinition.kt @@ -38,9 +38,5 @@ data class TileDefinition( .auto(TileDefinition::category) .auto(TileDefinition::renderTemplate) .auto(TileDefinition::renderParameters) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapterFactory(ADAPTER) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/SkyParameters.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/SkyParameters.kt index da361450..e83de053 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/SkyParameters.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/SkyParameters.kt @@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager import ru.dbotthepony.kstarbound.io.ColorTypeAdapter import ru.dbotthepony.kstarbound.io.json.builder.BuilderAdapter import ru.dbotthepony.kstarbound.io.json.builder.EnumAdapter +import ru.dbotthepony.kstarbound.registerTypeAdapter import ru.dbotthepony.kvector.vector.Color import ru.dbotthepony.kvector.vector.ndouble.Vector2d import kotlin.properties.ReadWriteProperty @@ -38,14 +39,6 @@ class SkyParameters { SkyParameters::surfaceLevel, SkyParameters::seed, ) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(SkyParameters::class.java, ADAPTER) - gsonBuilder.registerTypeAdapter(SkyColoringManifold::class.java, SkyColoringManifold.ADAPTER) - gsonBuilder.registerTypeAdapter(SkyColoring::class.java, SkyColoring.ADAPTER) - gsonBuilder.registerTypeAdapter(SkyType::class.java, EnumAdapter(SkyType::class)) - SkySatellite.registerGson(gsonBuilder) - } } } @@ -55,7 +48,7 @@ class SkyColoringManifold { companion object { val ADAPTER = object : TypeAdapter() { - override fun write(out: JsonWriter?, value: SkyColoringManifold?) { + override fun write(out: JsonWriter, value: SkyColoringManifold) { TODO("Not yet implemented") } @@ -151,10 +144,5 @@ class SkySatellite { ) private val LOGGER = LogManager.getLogger(SkySatellite::class.java) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(SkySatellite::class.java, ADAPTER) - gsonBuilder.registerTypeAdapter(Layer::class.java, LAYER_ADAPTER) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/dungeon/Configurable.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/dungeon/Configurable.kt index 868a87a1..485e811c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/dungeon/Configurable.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/dungeon/Configurable.kt @@ -48,11 +48,5 @@ class DungeonWorldDef { DungeonWorldDef::planetType, DungeonWorldDef::planetSize, ) - - fun registerGson(gsonBuilder: GsonBuilder) { - gsonBuilder.registerTypeAdapter(DungeonWorldDef::class.java, ADAPTER) - gsonBuilder.registerTypeAdapter(EnumAdapter(BeamUpRule::class)) - gsonBuilder.registerTypeAdapter(EnumAdapter(DungeonType::class)) - } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/ContextualizedTypeAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/ContextualizedTypeAdapter.kt new file mode 100644 index 00000000..8e329c40 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/ContextualizedTypeAdapter.kt @@ -0,0 +1,47 @@ +package ru.dbotthepony.kstarbound.io.json + +import com.google.gson.Gson +import com.google.gson.JsonElement +import com.google.gson.TypeAdapter +import com.google.gson.TypeAdapterFactory +import com.google.gson.internal.bind.JsonTreeReader +import com.google.gson.reflect.TypeToken +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter +import java.io.StringReader + +interface ContextualizedTypeAdapter { + fun write(writer: JsonWriter, value: T, gson: Gson) + + fun read(reader: JsonReader, gson: Gson): T + + fun read(value: String, gson: Gson): T { + return read(JsonReader(StringReader(value)), gson) + } + + fun read(value: JsonElement, gson: Gson): T { + return read(JsonTreeReader(value), gson) + } +} + +inline fun ContextualizedTypeAdapter.factory() = ContextualizedTypeAdapterWrapper(T::class.java, this) + +class ContextualizedTypeAdapterWrapper(val type: Class, val adapter: ContextualizedTypeAdapter) : TypeAdapterFactory { + override fun create(gson: Gson, type: TypeToken): TypeAdapter? { + if (this.type.isAssignableFrom(type.rawType)) { + return Adapter(gson) as TypeAdapter + } + + return null + } + + private inner class Adapter(private val gson: Gson) : TypeAdapter() { + override fun write(out: JsonWriter, value: T) { + return adapter.write(out, value, gson) + } + + override fun read(`in`: JsonReader): T { + return adapter.read(`in`, gson) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/Ext.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/Ext.kt index 371166f0..7c34857b 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/Ext.kt @@ -1,7 +1,10 @@ package ru.dbotthepony.kstarbound.io.json +import com.google.gson.Gson import com.google.gson.JsonSyntaxException 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.JsonToken import com.google.gson.stream.JsonWriter @@ -72,3 +75,12 @@ fun TypeAdapter.neverNull(): TypeAdapter { } fun TypeAdapter.allowNull(): TypeAdapter = nullSafe() + +@Deprecated("Небезопасно, надо использовать другой путь") +fun TypeAdapterFactory.ifString(reader: (String) -> Any): TypeAdapterFactory { + return object : TypeAdapterFactory { + override fun create(gson: Gson, type: TypeToken): TypeAdapter? { + return this@ifString.create(gson, type)?.ifString(reader as (String) -> T) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt index c2bddd5d..34589ff1 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt @@ -51,14 +51,14 @@ interface INativeJsonHolder : IJsonHolder { } @Suppress("FunctionName") -fun BuilderAdapter(factory: () -> T, vararg fields: KMutableProperty1): BuilderAdapter { +fun BuilderAdapter(factory: () -> T, vararg fields: KMutableProperty1): TypeAdapterFactory { val builder = BuilderAdapter.Builder(factory) for (field in fields) { builder.auto(field) } - return builder.build() + return builder } /** @@ -214,11 +214,11 @@ class BuilderAdapter private constructor( private val ignoreKeys = ObjectArraySet() var extraPropertiesAreFatal = false var logMisses: Boolean? = null - private val factoryReturnType by lazy { factory::invoke.returnType } + private val factoryReturnType by lazy { factory.invoke()::class.java } @OptIn(ExperimentalStdlibApi::class) override fun create(gson: Gson, type: TypeToken): TypeAdapter? { - if (type.isAssignableFrom(factoryReturnType.javaType)) { + if (type.isAssignableFrom(factoryReturnType)) { return build(gson) as TypeAdapter } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt index b113e4e3..70c46cee 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/FactoryAdapter.kt @@ -23,6 +23,7 @@ import ru.dbotthepony.kstarbound.defs.util.enrollList import ru.dbotthepony.kstarbound.defs.util.enrollMap import ru.dbotthepony.kstarbound.defs.util.flattenJsonElement import ru.dbotthepony.kstarbound.getValue +import ru.dbotthepony.kstarbound.io.json.ifString import ru.dbotthepony.kstarbound.io.json.util.LazyTypeProvider import ru.dbotthepony.kstarbound.io.json.util.ListAdapter import ru.dbotthepony.kstarbound.io.json.util.MapAdapter @@ -384,6 +385,12 @@ class FactoryAdapter private constructor( } private val types = ArrayList>() + private var stringTransformer: ((String) -> T)? = null + + fun ifString(transformer: (String) -> T): Builder { + stringTransformer = transformer + return this + } override fun create(gson: Gson, type: TypeToken): TypeAdapter? { if (type.rawType == clazz.java) { @@ -396,7 +403,7 @@ class FactoryAdapter private constructor( /** * Собирает этот [FactoryAdapter] с указанным GSON объектом */ - fun build(gson: Gson): FactoryAdapter { + fun build(gson: Gson): TypeAdapter { check(!asList || types.none { it.isFlat }) { "Can't have both flat properties and json data array layout" } return FactoryAdapter( @@ -405,7 +412,12 @@ class FactoryAdapter private constructor( asJsonArray = asList, storesJson = storesJson, logMisses = logMisses, - ) + ).let { + if (stringTransformer != null) + it.ifString(stringTransformer!!) + else + it + } } /** @@ -416,7 +428,7 @@ class FactoryAdapter private constructor( * Несмотря на @Deprecated, данный вариант метода удалён не будет */ @Deprecated("Используйте как TypeAdapterFactory") - fun build(): FactoryAdapter { + fun build(): TypeAdapter { check(!asList || types.none { it.isFlat }) { "Can't have both flat properties and json data array layout" } return FactoryAdapter( @@ -425,7 +437,12 @@ class FactoryAdapter private constructor( asJsonArray = asList, storesJson = storesJson, logMisses = logMisses, - ) + ).let { + if (stringTransformer != null) + it.ifString(stringTransformer!!) + else + it + } } /**