Skip to content
Snippets Groups Projects
Verified Commit e89b04e2 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

feat: unify state holder api

parent 121f7b0d
Branches
Tags
No related merge requests found
Showing
with 74 additions and 53 deletions
...@@ -15,4 +15,4 @@ plugins { ...@@ -15,4 +15,4 @@ plugins {
} }
group = "de.justjanne.libquassel" group = "de.justjanne.libquassel"
version = "0.7.0" version = "0.8.0"
...@@ -12,13 +12,14 @@ package de.justjanne.libquassel.client.session ...@@ -12,13 +12,14 @@ package de.justjanne.libquassel.client.session
import de.justjanne.libquassel.client.util.CoroutineQueue import de.justjanne.libquassel.client.util.CoroutineQueue
import de.justjanne.libquassel.protocol.syncables.ObjectIdentifier import de.justjanne.libquassel.protocol.syncables.ObjectIdentifier
import de.justjanne.libquassel.protocol.syncables.SyncableStub import de.justjanne.libquassel.protocol.syncables.SyncableStub
import de.justjanne.libquassel.protocol.util.StateHolder
import de.justjanne.libquassel.protocol.util.update import de.justjanne.libquassel.protocol.util.update
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
class BaseInitHandler( class BaseInitHandler(
private val session: ClientSession private val session: ClientSession
) { ) : StateHolder<BaseInitHandlerState> {
private val coroutineQueue = CoroutineQueue<Unit>() private val coroutineQueue = CoroutineQueue<Unit>()
fun sync(stub: SyncableStub) { fun sync(stub: SyncableStub) {
...@@ -45,12 +46,7 @@ class BaseInitHandler( ...@@ -45,12 +46,7 @@ class BaseInitHandler(
coroutineQueue.wait() coroutineQueue.wait()
} else Unit } else Unit
@Suppress("NOTHING_TO_INLINE") override fun state(): BaseInitHandlerState = state.value
inline fun state(): BaseInitHandlerState = state.value override fun flow(): Flow<BaseInitHandlerState> = state
private val state = MutableStateFlow(BaseInitHandlerState())
@Suppress("NOTHING_TO_INLINE")
inline fun flow(): Flow<BaseInitHandlerState> = state
@PublishedApi
internal val state = MutableStateFlow(BaseInitHandlerState())
} }
...@@ -38,6 +38,7 @@ import de.justjanne.libquassel.protocol.syncables.common.Network ...@@ -38,6 +38,7 @@ import de.justjanne.libquassel.protocol.syncables.common.Network
import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
import de.justjanne.libquassel.protocol.syncables.state.CertManagerState import de.justjanne.libquassel.protocol.syncables.state.CertManagerState
import de.justjanne.libquassel.protocol.syncables.state.NetworkState import de.justjanne.libquassel.protocol.syncables.state.NetworkState
import de.justjanne.libquassel.protocol.util.StateHolder
import de.justjanne.libquassel.protocol.util.log.info import de.justjanne.libquassel.protocol.util.log.info
import de.justjanne.libquassel.protocol.util.update import de.justjanne.libquassel.protocol.util.update
import de.justjanne.libquassel.protocol.variant.QVariantMap import de.justjanne.libquassel.protocol.variant.QVariantMap
...@@ -51,7 +52,7 @@ class ClientSession( ...@@ -51,7 +52,7 @@ class ClientSession(
protocolFeatures: ProtocolFeatures, protocolFeatures: ProtocolFeatures,
protocols: List<ProtocolMeta>, protocols: List<ProtocolMeta>,
sslContext: SSLContext sslContext: SSLContext
) : Session { ) : Session, StateHolder<ClientSessionState> {
override val side = ProtocolSide.CLIENT override val side = ProtocolSide.CLIENT
override val rpcHandler = ClientRpcHandler(this) override val rpcHandler = ClientRpcHandler(this)
...@@ -202,14 +203,9 @@ class ClientSession( ...@@ -202,14 +203,9 @@ class ClientSession(
override val networkConfig get() = state().networkConfig override val networkConfig get() = state().networkConfig
@Suppress("NOTHING_TO_INLINE") override fun state(): ClientSessionState = state.value
inline fun state(): ClientSessionState = state.value override fun flow(): Flow<ClientSessionState> = state
private val state = MutableStateFlow(
@Suppress("NOTHING_TO_INLINE")
inline fun flow(): Flow<ClientSessionState> = state
@PublishedApi
internal val state = MutableStateFlow(
ClientSessionState( ClientSessionState(
networks = mapOf(), networks = mapOf(),
identities = mapOf(), identities = mapOf(),
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
package de.justjanne.libquassel.protocol.io package de.justjanne.libquassel.protocol.io
import de.justjanne.libquassel.protocol.util.StateHolder
import de.justjanne.libquassel.protocol.util.update import de.justjanne.libquassel.protocol.util.update
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
...@@ -21,7 +22,7 @@ import java.nio.ByteBuffer ...@@ -21,7 +22,7 @@ import java.nio.ByteBuffer
import java.util.concurrent.Executors import java.util.concurrent.Executors
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
class CoroutineChannel { class CoroutineChannel : StateHolder<CoroutineChannelState> {
private lateinit var channel: StreamChannel private lateinit var channel: StreamChannel
private val writeContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher() private val writeContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
private val readContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher() private val readContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
...@@ -81,12 +82,7 @@ class CoroutineChannel { ...@@ -81,12 +82,7 @@ class CoroutineChannel {
} }
} }
@Suppress("NOTHING_TO_INLINE") override fun state(): CoroutineChannelState = state.value
inline fun state(): CoroutineChannelState = state.value override fun flow(): Flow<CoroutineChannelState> = state
private val state = MutableStateFlow(CoroutineChannelState())
@Suppress("NOTHING_TO_INLINE")
inline fun flow(): Flow<CoroutineChannelState> = state
@PublishedApi
internal val state = MutableStateFlow(CoroutineChannelState())
} }
...@@ -9,11 +9,12 @@ ...@@ -9,11 +9,12 @@
package de.justjanne.libquassel.protocol.syncables package de.justjanne.libquassel.protocol.syncables
import de.justjanne.libquassel.protocol.util.StateHolder
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import org.threeten.bp.Instant import org.threeten.bp.Instant
class HeartBeatHandler { class HeartBeatHandler : StateHolder<Long?> {
private var lastReceived: Instant? = null private var lastReceived: Instant? = null
/** /**
...@@ -30,14 +31,12 @@ class HeartBeatHandler { ...@@ -30,14 +31,12 @@ class HeartBeatHandler {
fun recomputeLatency(current: Instant, force: Boolean) { fun recomputeLatency(current: Instant, force: Boolean) {
val last = lastReceived?.toEpochMilli() ?: return val last = lastReceived?.toEpochMilli() ?: return
val roundtripLatency = current.toEpochMilli() - last val roundtripLatency = current.toEpochMilli() - last
if (force || roundtripLatency > this.roundtripLatency.value ?: return) { if (force || roundtripLatency > (this.roundtripLatency.value ?: return)) {
this.roundtripLatency.value = roundtripLatency this.roundtripLatency.value = roundtripLatency
} }
} }
@Suppress("NOTHING_TO_INLINE") override fun flow(): Flow<Long?> = roundtripLatency
inline fun flow(): Flow<Long?> = roundtripLatency override fun state(): Long? = roundtripLatency.value
private val roundtripLatency = MutableStateFlow<Long?>(null)
@PublishedApi
internal val roundtripLatency = MutableStateFlow<Long?>(null)
} }
...@@ -9,11 +9,12 @@ ...@@ -9,11 +9,12 @@
package de.justjanne.libquassel.protocol.syncables package de.justjanne.libquassel.protocol.syncables
import de.justjanne.libquassel.protocol.util.StateHolder
import de.justjanne.libquassel.protocol.util.update import de.justjanne.libquassel.protocol.util.update
import de.justjanne.libquassel.protocol.variant.QVariantMap import de.justjanne.libquassel.protocol.variant.QVariantMap
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
class ObjectRepository { class ObjectRepository : StateHolder<ObjectRepositoryState> {
fun add(syncable: SyncableStub): Boolean { fun add(syncable: SyncableStub): Boolean {
val identifier = ObjectIdentifier(syncable) val identifier = ObjectIdentifier(syncable)
if (syncable is StatefulSyncableStub) { if (syncable is StatefulSyncableStub) {
...@@ -78,12 +79,7 @@ class ObjectRepository { ...@@ -78,12 +79,7 @@ class ObjectRepository {
return find(T::class.java.simpleName, objectName) as? T return find(T::class.java.simpleName, objectName) as? T
} }
@Suppress("NOTHING_TO_INLINE") override fun state() = flow().value
inline fun state() = flow().value override fun flow() = state
private val state = MutableStateFlow(ObjectRepositoryState())
@Suppress("NOTHING_TO_INLINE")
inline fun flow() = state
@PublishedApi
internal val state = MutableStateFlow(ObjectRepositoryState())
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
package de.justjanne.libquassel.protocol.syncables package de.justjanne.libquassel.protocol.syncables
import de.justjanne.libquassel.protocol.session.Session import de.justjanne.libquassel.protocol.session.Session
import de.justjanne.libquassel.protocol.util.StateHolder
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
...@@ -17,7 +18,7 @@ abstract class StatefulSyncableObject<T>( ...@@ -17,7 +18,7 @@ abstract class StatefulSyncableObject<T>(
session: Session?, session: Session?,
className: String, className: String,
state: T state: T
) : SyncableObject(session, className), StatefulSyncableStub { ) : SyncableObject(session, className), StatefulSyncableStub, StateHolder<T> {
override fun toString(): String { override fun toString(): String {
return "$className(objectName=$objectName, state=${state()})" return "$className(objectName=$objectName, state=${state()})"
} }
...@@ -38,12 +39,7 @@ abstract class StatefulSyncableObject<T>( ...@@ -38,12 +39,7 @@ abstract class StatefulSyncableObject<T>(
return result return result
} }
@Suppress("NOTHING_TO_INLINE") override fun state(): T = state.value
inline fun state(): T = state.value override fun flow(): Flow<T> = state
protected val state = MutableStateFlow(state)
@Suppress("NOTHING_TO_INLINE")
inline fun flow(): Flow<T> = state
@PublishedApi
internal val state = MutableStateFlow(state)
} }
/*
* libquassel
* Copyright (c) 2022 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util
import kotlinx.coroutines.flow.Flow
interface StateHolder<T> {
fun state(): T
fun flow(): Flow<T>
}
/*
* libquassel
* Copyright (c) 2022 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
@ExperimentalCoroutinesApi
@Suppress("NOTHING_TO_INLINE")
inline fun <T> Flow<StateHolder<T>?>.flatMap(): Flow<T?> =
flatMapLatest { it?.flow() ?: emptyFlow() }
@ExperimentalCoroutinesApi
inline fun <reified T> Flow<Iterable<StateHolder<T>>?>.combineLatest(): Flow<List<T>> =
flatMapLatest { combine(it?.map(StateHolder<T>::flow).orEmpty(), ::listOf) }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment