From 37109a1764776c041a9f6092b588af4c34fd97e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 27 Oct 2019 18:15:00 +0100 Subject: [PATCH] Debounce Display Hosts and fix RegisteredHost equals --- .../metallic/chiaki/common/RegisteredHost.kt | 37 ++++++++++++++++++- .../chiaki/discovery/DiscoveryManager.kt | 31 ++++++++++++++-- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/java/com/metallic/chiaki/common/RegisteredHost.kt b/android/app/src/main/java/com/metallic/chiaki/common/RegisteredHost.kt index 080f854..a0c83e0 100644 --- a/android/app/src/main/java/com/metallic/chiaki/common/RegisteredHost.kt +++ b/android/app/src/main/java/com/metallic/chiaki/common/RegisteredHost.kt @@ -25,7 +25,6 @@ import io.reactivex.Flowable import io.reactivex.Maybe import io.reactivex.Single -@Suppress("ArrayInDataClass") @Entity(tableName = "registered_host") data class RegisteredHost( @PrimaryKey(autoGenerate = true) val id: Long = 0, @@ -51,6 +50,42 @@ data class RegisteredHost( rpKeyType = registHost.rpKeyType.toInt(), rpKey = registHost.rpKey ) + + override fun equals(other: Any?): Boolean + { + if(this === other) return true + if(javaClass != other?.javaClass) return false + + other as RegisteredHost + + if(id != other.id) return false + if(apSsid != other.apSsid) return false + if(apBssid != other.apBssid) return false + if(apKey != other.apKey) return false + if(apName != other.apName) return false + if(ps4Mac != other.ps4Mac) return false + if(ps4Nickname != other.ps4Nickname) return false + if(!rpRegistKey.contentEquals(other.rpRegistKey)) return false + if(rpKeyType != other.rpKeyType) return false + if(!rpKey.contentEquals(other.rpKey)) return false + + return true + } + + override fun hashCode(): Int + { + var result = id.hashCode() + result = 31 * result + (apSsid?.hashCode() ?: 0) + result = 31 * result + (apBssid?.hashCode() ?: 0) + result = 31 * result + (apKey?.hashCode() ?: 0) + result = 31 * result + (apName?.hashCode() ?: 0) + result = 31 * result + ps4Mac.hashCode() + result = 31 * result + (ps4Nickname?.hashCode() ?: 0) + result = 31 * result + rpRegistKey.contentHashCode() + result = 31 * result + rpKeyType + result = 31 * result + rpKey.contentHashCode() + return result + } } @Dao diff --git a/android/app/src/main/java/com/metallic/chiaki/discovery/DiscoveryManager.kt b/android/app/src/main/java/com/metallic/chiaki/discovery/DiscoveryManager.kt index 6446a54..a5edfca 100644 --- a/android/app/src/main/java/com/metallic/chiaki/discovery/DiscoveryManager.kt +++ b/android/app/src/main/java/com/metallic/chiaki/discovery/DiscoveryManager.kt @@ -25,12 +25,16 @@ import com.metallic.chiaki.lib.DiscoveryHost import com.metallic.chiaki.lib.DiscoveryService import com.metallic.chiaki.lib.DiscoveryServiceOptions import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.rxkotlin.addTo import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.Subject import java.lang.NumberFormatException import java.net.InetSocketAddress import java.nio.charset.Charset import java.nio.charset.StandardCharsets +import java.util.concurrent.TimeUnit val DiscoveryHost.ps4Mac get() = this.hostId?.hexToByteArray()?.let { if(it.size == MacAddress.LENGTH) @@ -47,6 +51,8 @@ class DiscoveryManager const val DROP_PINGS: ULong = 3U const val PING_MS: ULong = 500U const val PORT = 987 + + const val DEBOUNCE_EMPTY_MS = 1000L } private var discoveryService: DiscoveryService? = null @@ -62,10 +68,26 @@ class DiscoveryManager } private var paused = false - private var discoveredHostsSubject: Subject> = BehaviorSubject.create>().also { + private val disposable = CompositeDisposable() + + private var discoveredHostsSubjectDebounced: Subject> = BehaviorSubject.create>().also { it.onNext(listOf()) }.toSerialized() - val discoveredHosts: Observable> get() = discoveredHostsSubject + + private var discoveredHostsSubjectRaw: Subject> = BehaviorSubject.create>().also { subject -> + subject.debounce { hosts -> + if(hosts.isEmpty()) + Observable.timer(DEBOUNCE_EMPTY_MS, TimeUnit.MILLISECONDS) + else + Observable.empty() + } + .subscribe { hosts -> + discoveredHostsSubjectDebounced.onNext(hosts) + } + .addTo(disposable) + } + + val discoveredHosts: Observable> get() = discoveredHostsSubjectDebounced fun resume() { @@ -82,6 +104,7 @@ class DiscoveryManager fun dispose() { active = false + disposable.dispose() } fun sendWakeup(host: String, registKey: ByteArray) @@ -102,7 +125,7 @@ class DiscoveryManager { discoveryService = DiscoveryService(DiscoveryServiceOptions( HOSTS_MAX, DROP_PINGS, PING_MS, InetSocketAddress("255.255.255.255", PORT) - ), discoveredHostsSubject::onNext) + ), discoveredHostsSubjectRaw::onNext) } catch(e: CreateError) { @@ -114,7 +137,7 @@ class DiscoveryManager val service = discoveryService ?: return service.dispose() discoveryService = null - discoveredHostsSubject.onNext(listOf()) + discoveredHostsSubjectRaw.onNext(listOf()) } } } \ No newline at end of file