com.justai.jaicf.hook.BotHookHandler.kt Maven / Gradle / Ivy
package com.justai.jaicf.hook
import com.justai.jaicf.model.state.StatePath
import kotlin.reflect.KClass
data class BotHookListener(
val klass: KClass,
val action: (T) -> Unit,
val availableFrom: StatePath = StatePath.root(),
val exceptFrom: Set = setOf()
) {
fun execute(hook: T) {
val current = hook.context.dialogContext.currentContext.toString()
val isAvailable = current.startsWith(availableFrom.toString())
val isException = exceptFrom.any { current.startsWith(it.toString()) }
if (isAvailable && !isException) {
action.invoke(hook)
}
}
}
/**
* Holds a collection of [BotHook] handlers.
* @see BotHook
*/
class BotHookHandler {
val actions = mutableMapOf, MutableList>>()
/**
* Adds a listener for specified [BotHook]
*
* @param action a block that will be invoked once specified [BotHook] was triggered.
* @see BotHook
*/
inline fun addHookAction(noinline action: T.() -> Unit) {
val listener = BotHookListener(T::class, { hook: T -> hook.action() })
@Suppress("UNCHECKED_CAST")
actions.computeIfAbsent(T::class) { mutableListOf() }.add(listener as BotHookListener)
}
/**
* Invokes all listeners that are registered for a specified [BotHook].
* Mainly used by bot engine to trigger hook for every phase of request processing.
* You are free to create and trigger your own [BotHook] using the [BotHookHandler] as an event bus for your bot.
*
* @param hook a particular [BotHook] to be triggered
*/
fun triggerHook(hook: BotHook) {
actions[hook::class]?.forEach { listener ->
try {
listener.execute(hook)
} catch (e: BotHookException) {
throw e
} catch (e: Exception) {
}
}
}
internal inline fun hasHook() = actions[T::class] != null
}