Skip to content

Instantly share code, notes, and snippets.

@JoseAlcerreca
Created April 26, 2018 10:25
Show Gist options
  • Save JoseAlcerreca/5b661f1800e1e654f07cc54fe87441af to your computer and use it in GitHub Desktop.
Save JoseAlcerreca/5b661f1800e1e654f07cc54fe87441af to your computer and use it in GitHub Desktop.
An event wrapper for data that is exposed via a LiveData that represents an event.
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
@abdalin
Copy link

abdalin commented Jun 3, 2021

That looks nearly like my latest solution. However, I don't use a special EventObserver, since a Kotlin extension function can do the job:

class Event<out T>(private val content: T) {
    private val consumedScopes = HashSet<String>()

Adding more syntactic sugar to choirwire's contribution

class Event<out T>(private val content: T) {
    private val consumedScopes by lazy { HashSet<String>() }

    fun isConsumed(scope: String = "") = scope in consumedScopes

    @MainThread
    fun consume(scope: String = ""): T? {
        return content.takeIf { !isConsumed(scope) }?.also { consumedScopes.add(scope) }
    }

    fun peek(): T = content
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment