Do some code cleaning in field synchronizer
This commit is contained in:
parent
2095120abd
commit
5d8b770b94
@ -48,7 +48,7 @@ import kotlin.reflect.KProperty0
|
||||
* Universal, one-to-many value synchronizer, allowing to synchronize values from server to client
|
||||
* anywhere, where input/output streams are supported
|
||||
*/
|
||||
@Suppress("unused")
|
||||
@Suppress("unused", "BlockingMethodInNonBlockingContext")
|
||||
class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCallback: Boolean) {
|
||||
constructor() : this(Runnable {}, false)
|
||||
constructor(callback: Runnable) : this(callback, false)
|
||||
@ -485,6 +485,8 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
final override var isRemoved = false
|
||||
private set
|
||||
|
||||
protected var isDirty = false
|
||||
|
||||
override fun remove() {
|
||||
if (isRemoved)
|
||||
return
|
||||
@ -508,6 +510,12 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
endpoint.addDirtyField(this)
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this@AbstractField)
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -528,8 +536,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
}
|
||||
}
|
||||
|
||||
private var isDirty = false
|
||||
|
||||
private val access = object : FieldAccess<V> {
|
||||
override fun read(): V {
|
||||
return field
|
||||
@ -582,12 +588,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
this.field = value
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this@Field)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, endpoint: Endpoint) {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
codec.write(stream, field)
|
||||
@ -609,19 +609,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
}
|
||||
}
|
||||
|
||||
abstract inner class PrimitiveField<V : Any>() : AbstractField<V>() {
|
||||
protected var isDirty = false
|
||||
|
||||
abstract inner class PrimitiveField<V : Any> : AbstractField<V>() {
|
||||
override fun observe(): Boolean {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1022,7 +1014,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
) : AbstractField<V>(), IField<V> {
|
||||
private var remote: V? = null
|
||||
private var clientValue: V? = null
|
||||
private var isDirty = false
|
||||
|
||||
init {
|
||||
observers.add(this)
|
||||
@ -1042,12 +1033,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override val value: V
|
||||
get() = clientValue ?: getter.invoke()
|
||||
|
||||
@ -1075,7 +1060,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private var isRemoteSet = false
|
||||
private var clientValue: Float = 0f
|
||||
private var isClientValue = false
|
||||
private var isDirty = false
|
||||
|
||||
override val property = object : IFloatProperty {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Float {
|
||||
@ -1133,7 +1117,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
@Deprecated("Use type specific property", replaceWith = ReplaceWith("this.property"))
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Float {
|
||||
return super<IFloatField>.getValue(thisRef, property)
|
||||
return float
|
||||
}
|
||||
}
|
||||
|
||||
@ -1147,7 +1131,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private var isRemoteSet = false
|
||||
private var clientValue: Double = 0.0
|
||||
private var isClientValue = false
|
||||
private var isDirty = false
|
||||
|
||||
override val property = object : IDoubleProperty {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Double {
|
||||
@ -1174,12 +1157,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override val double: Double
|
||||
get() {
|
||||
if (isClientValue) {
|
||||
@ -1205,7 +1182,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
@Deprecated("Use type specific property", replaceWith = ReplaceWith("this.property"))
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Double {
|
||||
return super<IDoubleField>.getValue(thisRef, property)
|
||||
return double
|
||||
}
|
||||
}
|
||||
|
||||
@ -1219,7 +1196,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private var isRemoteSet = false
|
||||
protected var clientValue: Int = 0
|
||||
protected var isClientValue = false
|
||||
protected var isDirty = false
|
||||
|
||||
final override val property = object : IIntProperty {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Int {
|
||||
@ -1246,12 +1222,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
final override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
final override val int: Int
|
||||
get() {
|
||||
if (isClientValue) {
|
||||
@ -1263,7 +1233,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
@Deprecated("Use type specific property", replaceWith = ReplaceWith("this.property"))
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Int {
|
||||
return super<IIntField>.getValue(thisRef, property)
|
||||
return int
|
||||
}
|
||||
}
|
||||
|
||||
@ -1319,7 +1289,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private var isRemoteSet = false
|
||||
protected var clientValue: Long = 0L
|
||||
protected var isClientValue = false
|
||||
protected var isDirty = false
|
||||
|
||||
final override val property = object : ILongProperty {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Long {
|
||||
@ -1346,12 +1315,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
final override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
final override val long: Long
|
||||
get() {
|
||||
if (isClientValue) {
|
||||
@ -1363,7 +1326,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
@Deprecated("Use type specific property", replaceWith = ReplaceWith("this.property"))
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Long {
|
||||
return super<ILongField>.getValue(thisRef, property)
|
||||
return long
|
||||
}
|
||||
}
|
||||
|
||||
@ -1419,7 +1382,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private var isRemoteSet = false
|
||||
private var clientValue: Boolean = false
|
||||
private var isClientValue = false
|
||||
private var isDirty = false
|
||||
|
||||
override val property = object : IBooleanProperty {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||
@ -1446,12 +1408,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override val boolean: Boolean
|
||||
get() {
|
||||
if (isClientValue) {
|
||||
@ -1477,7 +1433,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
@Deprecated("Use type specific property", replaceWith = ReplaceWith("this.property"))
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||
return super<IBooleanField>.getValue(thisRef, property)
|
||||
return boolean
|
||||
}
|
||||
}
|
||||
|
||||
@ -1508,8 +1464,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
remote = codec.copy(value)
|
||||
}
|
||||
|
||||
private var isDirty = false
|
||||
|
||||
init {
|
||||
observers.add(this)
|
||||
}
|
||||
@ -1528,12 +1482,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, endpoint: Endpoint) {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
codec.write(stream, value)
|
||||
@ -1552,7 +1500,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private val callback: ((changes: Collection<SetChangeset<E>>) -> Unit)? = null,
|
||||
) : AbstractField<MutableSet<E>>() {
|
||||
private var isRemote = false
|
||||
private var isDirty = false
|
||||
|
||||
private fun pushBacklog(element: E, action: (DataOutputStream) -> Unit) {
|
||||
check(!isRemote) { "Field marked as remote" }
|
||||
@ -1585,12 +1532,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
super.remove()
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
override fun markDirty(endpoint: Endpoint) {
|
||||
super.markDirty(endpoint)
|
||||
|
||||
@ -1610,9 +1551,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
if (!isRemote) {
|
||||
markDirty()
|
||||
|
||||
val copy = codec.copy(element)
|
||||
|
||||
pushBacklog(element) {
|
||||
it.write(ChangesetAction.ADD.ordinal + 1)
|
||||
codec.write(it, element)
|
||||
codec.write(it, copy)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1668,6 +1611,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
if (!isRemote) {
|
||||
markDirty()
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
pushBacklog(lastElement as E) {
|
||||
it.write(ChangesetAction.REMOVE.ordinal + 1)
|
||||
codec.write(it, lastElement as E)
|
||||
@ -1683,9 +1627,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
if (!isRemote) {
|
||||
markDirty()
|
||||
|
||||
val copy = codec.copy(element)
|
||||
|
||||
pushBacklog(element) {
|
||||
it.write(ChangesetAction.REMOVE.ordinal + 1)
|
||||
codec.write(it, element)
|
||||
codec.write(it, copy)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1790,19 +1736,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private val keyCodec: IStreamCodec<K>,
|
||||
private val valueCodec: IStreamCodec<V>,
|
||||
private val backingMap: MutableMap<K, V>,
|
||||
private val observingBackingMap: MutableMap<K, V>? = null,
|
||||
private val callback: ((changes: Collection<MapChangeset<K, V>>) -> Unit)? = null,
|
||||
) : AbstractField<MutableMap<K, V>>(), IField<MutableMap<K, V>> {
|
||||
private var isDirty = false
|
||||
private var sentAllValues = false
|
||||
private var isRemote = false
|
||||
|
||||
init {
|
||||
if (observingBackingMap != null) {
|
||||
observers.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun pushBacklog(key: Any?, value: (DataOutputStream) -> Unit) {
|
||||
val pair = key to value
|
||||
|
||||
@ -1820,62 +1758,15 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearBacklog() {
|
||||
forEachEndpoint {
|
||||
it.getMapBacklog(this).clear()
|
||||
}
|
||||
}
|
||||
|
||||
override fun observe(): Boolean {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
|
||||
if (isRemote) {
|
||||
return false
|
||||
}
|
||||
|
||||
val observingBackingMap = observingBackingMap
|
||||
|
||||
if (observingBackingMap != null) {
|
||||
for ((key, value) in backingMap) {
|
||||
val remoteValue = observingBackingMap[key] ?: throw ConcurrentModificationException("Backing map of $this was modified externally, or $value missed a modification")
|
||||
|
||||
if (!valueCodec.compare(value, remoteValue)) {
|
||||
val valueCopy = valueCodec.copy(value)
|
||||
|
||||
pushBacklog(key) {
|
||||
it.write(ChangesetAction.ADD.ordinal + 1)
|
||||
keyCodec.write(it, key)
|
||||
valueCodec.write(it, valueCopy)
|
||||
}
|
||||
|
||||
observingBackingMap[key] = valueCopy
|
||||
|
||||
if (!isDirty) {
|
||||
notifyEndpoints(this)
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isDirty
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
|
||||
if (isRemote) {
|
||||
if (isRemote || endpoints.isEmpty())
|
||||
return
|
||||
}
|
||||
|
||||
if (endpoints.isEmpty()) {
|
||||
val observingBackingMap = observingBackingMap ?: return
|
||||
|
||||
for ((key, value) in backingMap)
|
||||
observingBackingMap[key] = valueCodec.copy(value)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
isDirty = true
|
||||
val backlogs = LinkedList<LinkedList<Pair<Any?, (DataOutputStream) -> Unit>>>()
|
||||
@ -1900,17 +1791,14 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
for (backlog in backlogs) {
|
||||
backlog.add(key to action)
|
||||
}
|
||||
|
||||
observingBackingMap?.put(key, valueCopy)
|
||||
}
|
||||
}
|
||||
|
||||
override fun markDirty(endpoint: Endpoint) {
|
||||
check(!isRemoved) { "Field was removed" }
|
||||
|
||||
if (isRemote) {
|
||||
if (isRemote)
|
||||
return
|
||||
}
|
||||
|
||||
val backlog = endpoint.getMapBacklog(this)
|
||||
|
||||
@ -1928,69 +1816,49 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
}
|
||||
}
|
||||
|
||||
private fun lmarkDirty() {
|
||||
if (!isDirty) {
|
||||
notifyEndpoints(this@Map)
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
override val value: MutableMap<K, V> = object : ProxiedMap<K, V>(backingMap) {
|
||||
override fun onClear() {
|
||||
if (isRemote) {
|
||||
if (isRemote || endpoints.isEmpty())
|
||||
return
|
||||
}
|
||||
|
||||
if (endpoints.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
observingBackingMap?.clear()
|
||||
|
||||
forEachEndpoint { endpoint ->
|
||||
endpoint.getMapBacklog(this@Map).also {
|
||||
endpoint.getMapBacklog(this@Map).let {
|
||||
it.clear()
|
||||
it.add(null to ClearBacklogEntry)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDirty) {
|
||||
notifyEndpoints(this@Map)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
lmarkDirty()
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
override fun onValueAdded(key: K, value: V) {
|
||||
if (isRemote) {
|
||||
if (isRemote || endpoints.isEmpty())
|
||||
return
|
||||
}
|
||||
|
||||
if (endpoints.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val keyCopy = keyCodec.copy(key)
|
||||
val valueCopy = valueCodec.copy(value)
|
||||
|
||||
pushBacklog(key) {
|
||||
@Suppress("BlockingMethodInNonBlockingContext") // false positive
|
||||
it.write(ChangesetAction.ADD.ordinal + 1)
|
||||
keyCodec.write(it, key)
|
||||
keyCodec.write(it, keyCopy)
|
||||
valueCodec.write(it, valueCopy)
|
||||
}
|
||||
|
||||
observingBackingMap?.put(key, valueCopy)
|
||||
|
||||
if (!isDirty) {
|
||||
notifyEndpoints(this@Map)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
hasChanges = true
|
||||
lmarkDirty()
|
||||
}
|
||||
|
||||
override fun onValueRemoved(key: K, value: V) {
|
||||
if (isRemote) {
|
||||
if (isRemote || endpoints.isEmpty())
|
||||
return
|
||||
}
|
||||
|
||||
if (endpoints.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val keyCopy = keyCodec.copy(key)
|
||||
|
||||
@ -2000,14 +1868,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
keyCodec.write(it, keyCopy)
|
||||
}
|
||||
|
||||
observingBackingMap?.remove(key)
|
||||
|
||||
if (!isDirty) {
|
||||
notifyEndpoints(this@Map)
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
hasChanges = true
|
||||
lmarkDirty()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2029,7 +1890,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
if (!isRemote) {
|
||||
isRemote = true
|
||||
forEachEndpoint { it.removeMapBacklog(this) }
|
||||
observingBackingMap?.clear()
|
||||
}
|
||||
|
||||
isDirty = false
|
||||
|
Loading…
Reference in New Issue
Block a user