Skip to content

Commit

Permalink
Fix problem with loss of result listener.
Browse files Browse the repository at this point in the history
Issue #130
  • Loading branch information
terrakok committed Nov 26, 2020
1 parent 608a32c commit f44410f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ abstract class BaseRouter {
private val resultWire = ResultWire()

/**
* Sets data listener with given key.
* Sets data listener with given key
* and returns [ResultListenerHandler] for availability to dispose subscription.
*
* After first call listener will be removed.
*/
fun setResultListener(key: String, listener: ResultListener) {
resultWire.setResultListener(key, listener)
fun setResultListener(
key: String,
listener: ResultListener
): ResultListenerHandler {
return resultWire.setResultListener(key, listener)
}

/**
Expand All @@ -32,6 +36,5 @@ abstract class BaseRouter {
*/
protected fun executeCommands(vararg commands: Command) {
commandBuffer.executeCommands(commands)
resultWire.flush()
}
}
28 changes: 14 additions & 14 deletions library/src/main/kotlin/com/github/terrakok/cicerone/ResultWire.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
package com.github.terrakok.cicerone

import java.lang.ref.WeakReference

/**
* Interface definition for a result callback.
*/
fun interface ResultListener {
fun onResult(data: Any)
}

internal class ResultWire {
private val listeners = mutableMapOf<String, WeakReference<ResultListener>>()
/**
* Handler for manual delete subscription and avoid leak
*/
fun interface ResultListenerHandler {
fun dispose()
}

fun setResultListener(key: String, listener: ResultListener) {
listeners[key] = WeakReference(listener)
}
internal class ResultWire {
private val listeners = mutableMapOf<String, ResultListener>()

fun sendResult(key: String, data: Any) {
listeners.remove(key)?.get()?.let { listener ->
listener.onResult(data)
fun setResultListener(key: String, listener: ResultListener): ResultListenerHandler {
listeners[key] = listener
return ResultListenerHandler {
listeners.remove(key)
}
}

fun flush() {
listeners.entries
.filter { it.value.get() == null }
.forEach { listeners.remove(it.key) }
fun sendResult(key: String, data: Any) {
listeners.remove(key)?.onResult(data)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.terrakok.cicerone.sample.mvp.animation.profile

import com.github.terrakok.cicerone.ResultListenerHandler
import com.github.terrakok.cicerone.Router
import com.github.terrakok.cicerone.sample.R
import com.github.terrakok.cicerone.sample.Screens.SelectPhoto
Expand All @@ -13,6 +14,7 @@ import moxy.MvpPresenter
class ProfilePresenter(
private val router: Router
) : MvpPresenter<ProfileView>() {
private var resultListenerHandler: ResultListenerHandler? = null

companion object {
private const val RESULT_KEY = "photo_result"
Expand All @@ -25,12 +27,17 @@ class ProfilePresenter(
}

fun onPhotoClicked() {
router.setResultListener(RESULT_KEY) { data ->
resultListenerHandler = router.setResultListener(RESULT_KEY) { data ->
viewState!!.showPhoto(data as Int)
}
router.navigateTo(SelectPhoto(RESULT_KEY))
}

override fun onDestroy() {
resultListenerHandler?.dispose()
super.onDestroy()
}

fun onBackPressed() {
router.exit()
}
Expand Down

0 comments on commit f44410f

Please sign in to comment.