From 6ea4d7a6abec216f366b6aa4f3b9664d6470984e Mon Sep 17 00:00:00 2001 From: DBotThePony <dbotthepony@yandex.ru> Date: Sun, 22 Jan 2023 23:24:06 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C=D1=8E=20=D0=BF=D0=B5=D1=80=D0=B5=D1=88=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=BD=D0=B0=20TypeAdapterFactory,=20=D0=BD=D0=B0=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kstarbound/StarboundJsonAdapters.kt | 6 ++- .../defs/item/ArmorItemPrototype.kt | 9 ++-- .../defs/item/CurrencyItemPrototype.kt | 7 +-- .../kstarbound/defs/item/ItemPrototype.kt | 10 ++--- .../io/json/builder/BuilderAdapter.kt | 2 +- .../json/factory/ArrayListAdapterFactory.kt | 17 +++++++ .../io/json/factory/ArrayListTypeAdapter.kt | 45 +++++++++++++++++++ 7 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt index fd392719..c47b199e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt @@ -52,14 +52,18 @@ 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.ArrayListAdapterFactory import ru.dbotthepony.kstarbound.io.json.factory.ImmutableCollectionAdapterFactory import ru.dbotthepony.kstarbound.math.PolyTypeAdapter fun addStarboundJsonAdapters(builder: GsonBuilder) { with(builder) { - // ImmutableList, и прочее + // ImmutableList, ImmutableSet, ImmutableMap registerTypeAdapterFactory(ImmutableCollectionAdapterFactory) + // ArrayList + registerTypeAdapterFactory(ArrayListAdapterFactory) + registerTypeAdapter(ColorTypeAdapter.nullSafe()) // математические классы diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt index 4141bdb4..d0e9fb7c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.kstarbound.defs.item +import com.google.common.collect.ImmutableList import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.defs.util.enrollMap import ru.dbotthepony.kstarbound.io.json.builder.BuilderAdapter @@ -9,13 +10,13 @@ import ru.dbotthepony.kstarbound.io.json.neverNull import ru.dbotthepony.kstarbound.util.NotNullVar class ArmorItemPrototype : ItemPrototype(), IArmorItemDefinition { - override var colorOptions: List<Map<String, String>> = listOf() + override var colorOptions: ImmutableList<Map<String, String>> = ImmutableList.of() override var maleFrames: IArmorItemDefinition.ArmorFrames by NotNullVar() override var femaleFrames: IArmorItemDefinition.ArmorFrames by NotNullVar() override var level: Double = 1.0 - override var leveledStatusEffects: List<LeveledStatusEffect> = listOf() + override var leveledStatusEffects: ImmutableList<LeveledStatusEffect> = ImmutableList.of() - override var scripts: List<String> = listOf() + override var scripts: ImmutableList<String> = ImmutableList.of() override var scriptDelta: Int = 1 override var armorType: ArmorPieceType by NotNullVar() @@ -60,7 +61,7 @@ class ArmorItemPrototype : ItemPrototype(), IArmorItemDefinition { companion object { val ADAPTER = BuilderAdapter.Builder(::ArmorItemPrototype) .also { addFields(it as BuilderAdapter.Builder<ItemPrototype>) } // безопасность: свойства родительского класса объявлены как final - .add(ArmorItemPrototype::colorOptions, Starbound.NULLABLE_STRING_ADAPTER.neverNull().asJsonObject().asList()) + .auto(ArmorItemPrototype::colorOptions) .auto(ArmorItemPrototype::maleFrames) .auto(ArmorItemPrototype::femaleFrames) .auto(ArmorItemPrototype::level) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt index 6bf524a3..1a5b1b00 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt @@ -1,13 +1,14 @@ package ru.dbotthepony.kstarbound.defs.item +import com.google.common.collect.ImmutableList import ru.dbotthepony.kstarbound.defs.util.enrollMap import ru.dbotthepony.kstarbound.io.json.builder.BuilderAdapter import ru.dbotthepony.kstarbound.util.NotNullVar class CurrencyItemPrototype : ItemPrototype(), ICurrencyItemDefinition { - override var pickupSoundsSmall: List<String> = listOf() - override var pickupSoundsMedium: List<String> = listOf() - override var pickupSoundsLarge: List<String> = listOf() + override var pickupSoundsSmall: ImmutableList<String> = ImmutableList.of() + override var pickupSoundsMedium: ImmutableList<String> = ImmutableList.of() + override var pickupSoundsLarge: ImmutableList<String> = ImmutableList.of() override var smallStackLimit: Long by NotNullVar() override var mediumStackLimit: Long by NotNullVar() override var currency: String by NotNullVar() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt index 014f8225..1bbb75c0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt @@ -14,16 +14,16 @@ open class ItemPrototype : IItemDefinition, INativeJsonHolder { final override var price: Long = 0L final override var rarity: ItemRarity = ItemRarity.COMMON final override var category: String? = null - final override var inventoryIcon: ArrayList<IItemDefinition.InventoryIcon>? = null - final override var itemTags: ArrayList<String> = ArrayList() - final override var learnBlueprintsOnPickup: ArrayList<String> = ArrayList() + final override var inventoryIcon: ImmutableList<IItemDefinition.InventoryIcon>? = null + final override var itemTags: ImmutableList<String> = ImmutableList.of() + final override var learnBlueprintsOnPickup: ImmutableList<String> = ImmutableList.of() final override var maxStack: Long = 9999L final override var eventCategory: String? = null final override var consumeOnPickup: Boolean = false - final override var pickupQuestTemplates: ArrayList<String> = ArrayList() + final override var pickupQuestTemplates: ImmutableList<String> = ImmutableList.of() final override var tooltipKind: ItemTooltipKind = ItemTooltipKind.NORMAL final override var twoHanded: Boolean = false - final override var radioMessagesOnPickup: ArrayList<String> = ArrayList() + final override var radioMessagesOnPickup: ImmutableList<String> = ImmutableList.of() final override var fuelAmount: Long? = null var descriptionData: ThingDescription by NotNullVar() 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 34589ff1..43b24d8c 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 @@ -218,7 +218,7 @@ class BuilderAdapter<T : Any> private constructor( @OptIn(ExperimentalStdlibApi::class) override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? { - if (type.isAssignableFrom(factoryReturnType)) { + if (type.rawType == factoryReturnType) { return build(gson) as TypeAdapter<T> } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt new file mode 100644 index 00000000..bd1a825d --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt @@ -0,0 +1,17 @@ +package ru.dbotthepony.kstarbound.io.json.factory + +import com.google.gson.Gson +import com.google.gson.TypeAdapter +import com.google.gson.TypeAdapterFactory +import com.google.gson.reflect.TypeToken +import java.lang.reflect.ParameterizedType + +object ArrayListAdapterFactory : TypeAdapterFactory { + override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? { + if (ArrayList::class.java.isAssignableFrom(type.rawType) && type.type is ParameterizedType) { + return ArrayListTypeAdapter(gson.getAdapter(TypeToken.get((type.type as ParameterizedType).actualTypeArguments[0]))).nullSafe() as TypeAdapter<T> + } + + return null + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt new file mode 100644 index 00000000..8a1d6064 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt @@ -0,0 +1,45 @@ +package ru.dbotthepony.kstarbound.io.json.factory + +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonToken +import com.google.gson.stream.JsonWriter +import java.util.ArrayList + +class ArrayListTypeAdapter<E>(val elementAdapter: TypeAdapter<E>) : TypeAdapter<java.util.ArrayList<E>>() { + override fun write(out: JsonWriter, value: ArrayList<E>) { + if (value.size == 1) { + elementAdapter.write(out, value[0]) + return + } + + out.beginArray() + + for (v in value) { + elementAdapter.write(out, v) + } + + out.endArray() + } + + override fun read(reader: JsonReader): ArrayList<E> { + if (reader.peek() != JsonToken.BEGIN_ARRAY) { + // не массив, возможно упрощение структуры "a": [value] -> "a": value + val list = ArrayList<E>(1) + list.add(elementAdapter.read(reader)) + return list + } + + reader.beginArray() + + val list = ArrayList<E>() + + while (reader.peek() != JsonToken.END_ARRAY) { + list.add(elementAdapter.read(reader)) + } + + reader.endArray() + + return list + } +}