Больше свойств у прототипа предмета
This commit is contained in:
parent
5f3c33d9cb
commit
5e29072fcf
@ -3,6 +3,8 @@ package ru.dbotthepony.kstarbound.defs.item
|
||||
import com.google.gson.GsonBuilder
|
||||
import ru.dbotthepony.kstarbound.io.KConcreteTypeAdapter
|
||||
import ru.dbotthepony.kstarbound.registerTypeAdapter
|
||||
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
||||
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
||||
|
||||
data class ItemDefinition(
|
||||
val itemName: String,
|
||||
@ -12,8 +14,71 @@ data class ItemDefinition(
|
||||
val inventoryIcon: String? = null,
|
||||
val description: String = "...",
|
||||
val shortdescription: String = "...",
|
||||
val itemTags: List<String> = listOf()
|
||||
val itemTags: List<String> = listOf(),
|
||||
val learnBlueprintsOnPickup: List<String> = listOf(),
|
||||
val maxStack: Long = 9999L,
|
||||
val eventCategory: String? = null,
|
||||
val consumeOnPickup: Boolean = false,
|
||||
val pickupQuestTemplates: List<String> = listOf(),
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val race: String? = null,
|
||||
val displayImage: String? = null,
|
||||
val displayoffset: Vector2d? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val fossilSetName: String? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val setIndex: Int? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val setCount: Int? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val setCollectables: Map<String, String>? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val completeFossilIcon: String? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val completeFossilObject: String? = null,
|
||||
|
||||
/**
|
||||
* Используется в костях-ископаемых
|
||||
*/
|
||||
val completeSetDescriptions: FossilSetDescription? = null,
|
||||
|
||||
/**
|
||||
* Заставляет SAIL болтать
|
||||
*/
|
||||
val radioMessagesOnPickup: List<String> = listOf(),
|
||||
|
||||
/**
|
||||
* Топливо корабля
|
||||
*/
|
||||
val fuelAmount: Long? = null,
|
||||
) {
|
||||
data class FossilSetDescription(
|
||||
val price: Long = 0L,
|
||||
val shortdescription: String = "...",
|
||||
val description: String = "..."
|
||||
)
|
||||
|
||||
companion object {
|
||||
val ADAPTER = KConcreteTypeAdapter.Builder(ItemDefinition::class)
|
||||
.plain(ItemDefinition::itemName)
|
||||
@ -23,11 +88,40 @@ data class ItemDefinition(
|
||||
.plain(ItemDefinition::inventoryIcon)
|
||||
.plain(ItemDefinition::description)
|
||||
.plain(ItemDefinition::shortdescription)
|
||||
|
||||
.list(ItemDefinition::itemTags)
|
||||
.list(ItemDefinition::learnBlueprintsOnPickup)
|
||||
|
||||
.plain(ItemDefinition::maxStack)
|
||||
.plain(ItemDefinition::eventCategory)
|
||||
.plain(ItemDefinition::consumeOnPickup)
|
||||
.list(ItemDefinition::pickupQuestTemplates)
|
||||
|
||||
.plain(ItemDefinition::race)
|
||||
.plain(ItemDefinition::displayImage)
|
||||
.plain(ItemDefinition::displayoffset)
|
||||
.plain(ItemDefinition::fossilSetName)
|
||||
.plain(ItemDefinition::setIndex)
|
||||
.plain(ItemDefinition::setCount)
|
||||
.map(ItemDefinition::setCollectables, String::class)
|
||||
.plain(ItemDefinition::completeFossilIcon)
|
||||
.plain(ItemDefinition::completeFossilObject)
|
||||
|
||||
.plain(ItemDefinition::completeSetDescriptions)
|
||||
.list(ItemDefinition::radioMessagesOnPickup)
|
||||
.plain(ItemDefinition::fuelAmount)
|
||||
|
||||
.build()
|
||||
|
||||
val FOSSIL_ADAPTER = KConcreteTypeAdapter.Builder(FossilSetDescription::class)
|
||||
.plain(FossilSetDescription::price)
|
||||
.plain(FossilSetDescription::shortdescription)
|
||||
.plain(FossilSetDescription::description)
|
||||
.build()
|
||||
|
||||
fun registerGson(gsonBuilder: GsonBuilder) {
|
||||
gsonBuilder.registerTypeAdapter(ADAPTER)
|
||||
gsonBuilder.registerTypeAdapter(FOSSIL_ADAPTER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package ru.dbotthepony.kstarbound.io
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import com.google.common.collect.Interner
|
||||
import com.google.common.collect.Interners
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.internal.bind.TypeAdapters
|
||||
@ -18,19 +18,19 @@ import ru.dbotthepony.kstarbound.Starbound
|
||||
import ru.dbotthepony.kstarbound.getValue
|
||||
import ru.dbotthepony.kstarbound.setValue
|
||||
import java.lang.reflect.Constructor
|
||||
import java.util.BitSet
|
||||
import kotlin.jvm.internal.DefaultConstructorMarker
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.full.isSuperclassOf
|
||||
import kotlin.reflect.full.isSupertypeOf
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
private fun <T> resolveBound(bound: Class<T>): TypeAdapter<T> {
|
||||
private fun <T> resolveBound(bound: Class<T>, stringAdapter: TypeAdapter<String>): TypeAdapter<T> {
|
||||
return when (bound) {
|
||||
Float::class.java -> TypeAdapters.FLOAT as TypeAdapter<T>
|
||||
Double::class.java -> TypeAdapters.DOUBLE as TypeAdapter<T>
|
||||
String::class.java -> TypeAdapters.STRING as TypeAdapter<T>
|
||||
String::class.java -> stringAdapter as TypeAdapter<T>
|
||||
Int::class.java -> TypeAdapters.INTEGER as TypeAdapter<T>
|
||||
Long::class.java -> TypeAdapters.LONG as TypeAdapter<T>
|
||||
Boolean::class.java -> TypeAdapters.BOOLEAN as TypeAdapter<T>
|
||||
@ -38,10 +38,8 @@ private fun <T> resolveBound(bound: Class<T>): TypeAdapter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class ListAdapter<T>(private val bound: Class<T>) : TypeAdapter<List<T>>() {
|
||||
private val resolvedBound by lazy {
|
||||
resolveBound(bound)
|
||||
}
|
||||
private class ListAdapter<T>(private val bound: Class<T>, private val stringAdapter: TypeAdapter<String>) : TypeAdapter<List<T>>() {
|
||||
private val resolvedBound by lazy { resolveBound(bound, stringAdapter) }
|
||||
|
||||
override fun write(out: JsonWriter, value: List<T>) {
|
||||
out.beginArray()
|
||||
@ -72,14 +70,9 @@ class ListAdapter<T>(private val bound: Class<T>) : TypeAdapter<List<T>>() {
|
||||
}
|
||||
}
|
||||
|
||||
class MapAdapter<K, V>(private val boundKey: Class<K>, private val boundValue: Class<V>) : TypeAdapter<Map<K, V>>() {
|
||||
private val resolvedKey by lazy {
|
||||
resolveBound(boundKey)
|
||||
}
|
||||
|
||||
private val resolvedValue by lazy {
|
||||
resolveBound(boundValue)
|
||||
}
|
||||
private class MapAdapter<K, V>(private val boundKey: Class<K>, private val boundValue: Class<V>, private val stringAdapter: TypeAdapter<String>) : TypeAdapter<Map<K, V>>() {
|
||||
private val resolvedKey by lazy { resolveBound(boundKey, stringAdapter) }
|
||||
private val resolvedValue by lazy { resolveBound(boundValue, stringAdapter) }
|
||||
|
||||
override fun write(out: JsonWriter, value: Map<K, V>) {
|
||||
out.beginArray()
|
||||
@ -117,10 +110,8 @@ class MapAdapter<K, V>(private val boundKey: Class<K>, private val boundValue: C
|
||||
}
|
||||
}
|
||||
|
||||
class StringMapAdapter<V>(private val bound: Class<V>) : TypeAdapter<Map<String, V>>() {
|
||||
private val resolvedBound by lazy {
|
||||
resolveBound(bound)
|
||||
}
|
||||
private class StringMapAdapter<V>(private val bound: Class<V>, private val stringAdapter: TypeAdapter<String>, private val interner: () -> Interner<String>) : TypeAdapter<Map<String, V>>() {
|
||||
private val resolvedBound by lazy { resolveBound(bound, stringAdapter) }
|
||||
|
||||
override fun write(out: JsonWriter, value: Map<String, V>) {
|
||||
val resolvedBound = resolvedBound
|
||||
@ -143,7 +134,7 @@ class StringMapAdapter<V>(private val bound: Class<V>) : TypeAdapter<Map<String,
|
||||
val resolvedBound = resolvedBound
|
||||
|
||||
while (reader.peek() != JsonToken.END_OBJECT) {
|
||||
builder.put(reader.nextName(), resolvedBound.read(reader))
|
||||
builder.put(interner.invoke().intern(reader.nextName()), resolvedBound.read(reader))
|
||||
}
|
||||
|
||||
reader.endObject()
|
||||
@ -153,7 +144,7 @@ class StringMapAdapter<V>(private val bound: Class<V>) : TypeAdapter<Map<String,
|
||||
}
|
||||
|
||||
private class LazyTypeProvider<T : Any?>(private val bound: Class<T>) : TypeAdapter<T>() {
|
||||
private val resolved by lazy { resolveBound(bound) }
|
||||
private val resolved by lazy { resolveBound(bound, TypeAdapters.STRING) }
|
||||
|
||||
override fun write(out: JsonWriter, value: T) {
|
||||
resolved.write(out, value)
|
||||
@ -441,6 +432,17 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
*/
|
||||
class Builder<T : Any>(val clazz: KClass<T>) {
|
||||
private val types = ArrayList<Pair<KProperty1<T, *>, TypeAdapter<*>>>()
|
||||
private var interner by Delegates.notNull<Interner<String>>()
|
||||
|
||||
private val internedStringAdapter: TypeAdapter<String> = object : TypeAdapter<String>() {
|
||||
override fun write(out: JsonWriter, value: String) {
|
||||
return TypeAdapters.STRING.write(out, value)
|
||||
}
|
||||
|
||||
override fun read(`in`: JsonReader): String {
|
||||
return interner.intern(TypeAdapters.STRING.read(`in`))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет поле с определённым адаптером
|
||||
@ -467,7 +469,7 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
} else if (classifier.isSuperclassOf(Long::class)) {
|
||||
types.add(field to TypeAdapters.LONG)
|
||||
} else if (classifier.isSuperclassOf(String::class)) {
|
||||
types.add(field to TypeAdapters.STRING)
|
||||
types.add(field to internedStringAdapter)
|
||||
} else if (classifier.isSuperclassOf(Boolean::class)) {
|
||||
types.add(field to TypeAdapters.BOOLEAN)
|
||||
} else {
|
||||
@ -498,7 +500,7 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
* Список неизменяем (создаётся объект [ImmutableList])
|
||||
*/
|
||||
fun <V : Any> list(field: KProperty1<T, List<V>?>, type: Class<V>): Builder<T> {
|
||||
types.add(field to ListAdapter(type))
|
||||
types.add(field to ListAdapter(type, internedStringAdapter))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -517,7 +519,7 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
* Таблица неизменяема (создаётся объект [ImmutableMap])
|
||||
*/
|
||||
fun <K, V> map(field: KProperty1<T, Map<K, V>>, keyType: Class<K>, valueType: Class<V>): Builder<T> {
|
||||
types.add(field to MapAdapter(keyType, valueType))
|
||||
types.add(field to MapAdapter(keyType, valueType, internedStringAdapter))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -526,8 +528,8 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
*
|
||||
* Таблица неизменяема (создаётся объект [ImmutableMap])
|
||||
*/
|
||||
fun <K : Any, V : Any> map(field: KProperty1<T, Map<K, V>>, keyType: KClass<K>, valueType: KClass<V>): Builder<T> {
|
||||
types.add(field to MapAdapter(keyType.java, valueType.java))
|
||||
fun <K : Any, V : Any> map(field: KProperty1<T, Map<K, V>?>, keyType: KClass<K>, valueType: KClass<V>): Builder<T> {
|
||||
types.add(field to MapAdapter(keyType.java, valueType.java, internedStringAdapter))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -536,8 +538,8 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
*
|
||||
* Таблица неизменяема (создаётся объект [ImmutableMap])
|
||||
*/
|
||||
fun <V> map(field: KProperty1<T, Map<String, V>>, valueType: Class<V>): Builder<T> {
|
||||
types.add(field to StringMapAdapter(valueType))
|
||||
fun <V> map(field: KProperty1<T, Map<String, V>?>, valueType: Class<V>): Builder<T> {
|
||||
types.add(field to StringMapAdapter(valueType, internedStringAdapter, ::interner))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -546,17 +548,29 @@ class KConcreteTypeAdapter<T : Any>(
|
||||
*
|
||||
* Таблица неизменяема (создаётся объект [ImmutableMap])
|
||||
*/
|
||||
fun <V : Any> map(field: KProperty1<T, Map<String, V>>, valueType: KClass<V>): Builder<T> {
|
||||
types.add(field to StringMapAdapter(valueType.java))
|
||||
fun <V : Any> map(field: KProperty1<T, Map<String, V>?>, valueType: KClass<V>): Builder<T> {
|
||||
types.add(field to StringMapAdapter(valueType.java, internedStringAdapter, ::interner))
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(asList: Boolean = false): KConcreteTypeAdapter<T> {
|
||||
return KConcreteTypeAdapter(clazz, ImmutableList.copyOf(types), asList = asList)
|
||||
return KConcreteTypeAdapter(clazz, ImmutableList.copyOf(types), asList = asList).also {
|
||||
interner = it.internedStrings
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
|
||||
/*fun <T : Any> simple(clazz: KClass<T>, asList: Boolean = false): KConcreteTypeAdapter<T> {
|
||||
val builder = Builder(clazz)
|
||||
|
||||
for (argument in clazz.primaryConstructor!!.parameters) {
|
||||
builder.plain(argument.)
|
||||
}
|
||||
|
||||
return builder.build(asList = asList)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user