You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.5 KiB
Kotlin
75 lines
2.5 KiB
Kotlin
package me.eater.hefbrug.state
|
|
|
|
import me.eater.hefbrug.state.property.ExtendedPropertyDelegate
|
|
import me.eater.hefbrug.state.property.PropertyDelegate
|
|
import kotlin.reflect.KProperty
|
|
|
|
abstract class AbstractState(val id: String) {
|
|
val properties: MutableMap<String, PropertyDelegate<*>> = mutableMapOf()
|
|
|
|
protected fun <T> state(
|
|
default: T? = null,
|
|
required: Boolean = false,
|
|
writeOnce: Boolean = false
|
|
): PropertyDelegate<T> =
|
|
state<T>(required, writeOnce) { default }
|
|
|
|
protected fun <T> extState(
|
|
default: T? = null,
|
|
required: Boolean = false,
|
|
writeOnce: Boolean = false,
|
|
equals: ExtendedPropertyDelegate.DiffScope<T>.() -> Boolean
|
|
): ExtendedPropertyDelegate<T> =
|
|
extState<T>(required, writeOnce, { default }, equals)
|
|
|
|
protected fun <T> state(required: Boolean = false, writeOnce: Boolean = false, default: () -> T?) =
|
|
PropertyDelegate<T>(default, required, writeOnce)
|
|
|
|
protected fun <T> extState(
|
|
required: Boolean = false,
|
|
writeOnce: Boolean = false,
|
|
default: () -> T?,
|
|
equals: ExtendedPropertyDelegate.DiffScope<T>.() -> Boolean
|
|
) =
|
|
ExtendedPropertyDelegate<T>(default, required, writeOnce, equals)
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
operator fun <T> get(property: KProperty<T>): PropertyDelegate<T> =
|
|
(properties[property.name] as? PropertyDelegate<T>)!!
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
operator fun get(property: String): PropertyDelegate<*> =
|
|
properties[property]!!
|
|
|
|
override fun toString(): String =
|
|
"${this::class.simpleName ?: "State"}[id=$id] {${if (properties.isNotEmpty())
|
|
"\n ${this.properties.map { (k, v) -> "[$k]: ${v.get()}" }.joinToString("\n ")}\n"
|
|
else ""
|
|
}}"
|
|
|
|
open fun diff(currentState: AbstractState): Set<String> {
|
|
if (javaClass != currentState.javaClass) {
|
|
error("When diffing states both should be the same kind of state")
|
|
}
|
|
|
|
val changed = mutableSetOf<String>()
|
|
for ((name, property) in properties) {
|
|
val otherProperty = currentState.properties[name] ?: continue
|
|
|
|
if (property is ExtendedPropertyDelegate<*> && otherProperty is ExtendedPropertyDelegate<*>) {
|
|
if (property.hasChanged(otherProperty)) {
|
|
changed.add(name)
|
|
}
|
|
} else {
|
|
if (property.get() != otherProperty.get()) {
|
|
changed.add(name)
|
|
}
|
|
}
|
|
}
|
|
|
|
return changed
|
|
}
|
|
|
|
|
|
} |