Skip to content

Commit

Permalink
🐛: fix useEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
junerver committed Jul 31, 2024
1 parent 55df7db commit fcdac84
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
4 changes: 2 additions & 2 deletions hooks/src/main/kotlin/xyz/junerver/compose/hooks/declare.kt
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ fun rememberDisableScreenshot(): Tuple3<DisableFn, EnableFn, IsDisabled> = useDi

//region useEvent
@Composable
inline fun <reified T> rememberEventSubscribe(noinline subscriber: (T) -> Unit) =
inline fun <reified T : Any> rememberEventSubscribe(noinline subscriber: (T) -> Unit) =
useEventSubscribe(subscriber)

@Composable
inline fun <reified T> rememberEventPublish(): (T) -> Unit = useEventPublish()
inline fun <reified T : Any> rememberEventPublish(): (T) -> Unit = useEventPublish()
//endregion

@Composable
Expand Down
79 changes: 62 additions & 17 deletions hooks/src/main/kotlin/xyz/junerver/compose/hooks/useEvent.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package xyz.junerver.compose.hooks

import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import kotlin.reflect.KClass
import org.jetbrains.annotations.NotNull

/*
Description: More convenient communication between components, just like using EventBus
Expand Down Expand Up @@ -52,16 +55,17 @@ import kotlin.reflect.KClass
* Call the post function at the appropriate time and pass your event
* object.
*/
object EventManager {
val subscriberMap = mutableMapOf<KClass<*>, MutableList<(Any) -> Unit>>()
internal object EventManager {
// 对外使用的事件订阅模式不允许传递 null
private val subscriberMap = mutableMapOf<KClass<*>, MutableList<(Any) -> Unit>>()
private val aliasSubscriberMap = mutableMapOf<String, MutableList<(Any?) -> Unit>>()

@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> register(noinline subscriber: (T) -> Unit): () -> Unit {
subscriberMap[T::class] ?: run { subscriberMap[T::class] = mutableListOf() }
subscriberMap[T::class]?.add(subscriber as (Any) -> Unit)
internal fun <T : Any> register(clazz: KClass<*>, subscriber: (T) -> Unit): () -> Unit {
subscriberMap[clazz] ?: run { subscriberMap[clazz] = mutableListOf() }
subscriberMap[clazz]?.add(subscriber as (Any) -> Unit)
return {
subscriberMap[T::class]?.remove(subscriber)
subscriberMap[clazz]?.remove(subscriber)
}
}

Expand All @@ -74,9 +78,9 @@ object EventManager {
}
}

inline fun <reified T> post(event: T) {
if (subscriberMap.containsKey(T::class)) {
subscriberMap[T::class]?.forEach { it.invoke(event) }
internal fun <T> post(event: T & Any, clazz: KClass<*>) {
if (subscriberMap.containsKey(clazz)) {
subscriberMap[clazz]?.forEach { it.invoke(event) }
}
}

Expand All @@ -87,6 +91,30 @@ object EventManager {
}
}

/**
* Delegate post
*
* @param event
* @param clazz
* @param T
*/
@InternalComposeApi
fun <T> delegatePost(event: T & Any, clazz: KClass<*>) {
EventManager.post(event, clazz)
}

/**
* Delegate register
*
* @param clazz
* @param subscriber
* @param T
* @receiver
*/
@InternalComposeApi
fun <T> delegateRegister(clazz: KClass<*>, subscriber: (T) -> Unit) =
EventManager.register(clazz, subscriber)

/**
* Register a subscriber. Note that this subscription function will be
* removed from the subscription list after the component is uninstalled.
Expand All @@ -95,20 +123,42 @@ object EventManager {
* @param T
* @receiver
*/
@OptIn(InternalComposeApi::class)
@Composable
inline fun <reified T> useEventSubscribe(noinline subscriber: (T) -> Unit) {
inline fun <reified T : Any> useEventSubscribe(noinline subscriber: (T) -> Unit) {
val latest by useLatestState(subscriber)
val unSubscribeRef = useRef<(() -> Unit)?>(null)

useMount {
unSubscribeRef.current = EventManager.register(latest)
unSubscribeRef.current = delegateRegister(T::class, latest)
}

useUnmount {
unSubscribeRef.current?.invoke()
}
}

/**
* This hook returns a publish function, use that fun to post a event.
*
* @param T
* @return
*/
@OptIn(InternalComposeApi::class)
@Composable
inline fun <reified T : Any> useEventPublish(): (@NotNull T) -> Unit = remember {
{ event: T -> delegatePost(event, T::class) }
}

/**
* 仅在库内部使用的事件订阅
*
* @param alias
* @param subscriber
* @param T
* @receiver
*/
@SuppressLint("ComposableNaming")
@Composable
internal fun <T> useEventSubscribe(alias: String, subscriber: (T?) -> Unit) {
val latest by useLatestState(subscriber)
Expand All @@ -124,16 +174,11 @@ internal fun <T> useEventSubscribe(alias: String, subscriber: (T?) -> Unit) {
}

/**
* This hook returns a publish function, use that fun to post a event.
* 仅在库内部使用的事件发布
*
* @param T
* @return
*/
@Composable
inline fun <reified T> useEventPublish(): (T) -> Unit = remember {
{ event: T -> EventManager.post(event) }
}

@Composable
internal fun <T> useEventPublish(alias: String): (T) -> Unit = remember {
{ event: T -> EventManager.post(alias, event) }
Expand Down

0 comments on commit fcdac84

Please sign in to comment.