Add waitForNextAfterAction, queueAndWaitForNext

This commit is contained in:
2026-09-15 03:08:34 +01:00
parent cc0719a061
commit 521dc00757
@@ -1,6 +1,7 @@
package com.shr4pnel.ferretirc package com.shr4pnel.ferretirc
import com.shr4pnel.ferretirc.irc.Server import com.shr4pnel.ferretirc.irc.Server
import com.shr4pnel.ferretirc.irc.User
import com.shr4pnel.ferretirc.net.Connection import com.shr4pnel.ferretirc.net.Connection
import com.shr4pnel.ferretirc.net.messages.ClientMessage import com.shr4pnel.ferretirc.net.messages.ClientMessage
import com.shr4pnel.ferretirc.net.messages.ServerMessage import com.shr4pnel.ferretirc.net.messages.ServerMessage
@@ -24,7 +25,12 @@ class IrcClient(
private val logger = if (enableLogging) KotlinLogging.logger {} else KotlinLogging.logger(NOPLogger.NOP_LOGGER) private val logger = if (enableLogging) KotlinLogging.logger {} else KotlinLogging.logger(NOPLogger.NOP_LOGGER)
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
lateinit var server: Server lateinit var server: Server
private set
lateinit var currentUser: User
private set
@PublishedApi @PublishedApi
internal val connection = Connection(hostname, port, scope, enableLogging) internal val connection = Connection(hostname, port, scope, enableLogging)
@@ -64,17 +70,43 @@ class IrcClient(
} }
/** /**
* Return the next Server Message meeting condition * Return the next Server Message meeting given condition "predicate"
* @param predicate A function to filter a message based on its parameters * @param predicate A function to filter a message based on its parameters
* @param T A ServerMessage inheritor
* @return An instance of ServerMessage
* @see com.shr4pnel.ferretirc.irc.Server.waitForNext
* @see com.shr4pnel.ferretirc.net.messages.ServerMessage
*/ */
suspend inline fun <reified T : ServerMessage> waitForNext(noinline predicate: (T) -> Boolean = { true }): T = suspend inline fun <reified T : ServerMessage> waitForNext(noinline predicate: (T) -> Boolean = { true }): T =
connection.reader.waitForNext(T::class, predicate) server.waitForNext(T::class, predicate)
/**
* Queue a client message, and wait for the next server message meeting condition (predicate)
* @param predicate A function to filter a message based on its parameters
* @see com.shr4pnel.ferretirc.IrcClient.waitForNext
*/
suspend inline fun <reified T : ServerMessage> queueAndWaitForNext(
message: ClientMessage,
noinline predicate: (T) -> Boolean = { true },
): T = server.waitForNext(T::class, predicate) { queueMessage(message) }
/**
* Create a subscription to the server message buffer, after performing an action
* @param predicate A function to filter the message buffer flow
* @param action A function to execute after message buffer flow collection has begun
* @see com.shr4pnel.ferretirc.IrcClient.waitForNext
*/
suspend inline fun <reified T : ServerMessage> waitForNextAfterAction(
noinline predicate: (T) -> Boolean = { true },
noinline action: suspend () -> Unit,
): T = server.waitForNext(T::class, predicate, action)
suspend fun register( suspend fun register(
nick: String, nick: String,
realName: String? = null, realName: String? = null,
password: String? = null, password: String? = null,
) { ) {
currentUser = User(nick, "") // TODO TEMP USER ASSIGNMENT
val messages = val messages =
buildList { buildList {
if (!password.isNullOrEmpty()) add(ClientMessage.Pass(password)) if (!password.isNullOrEmpty()) add(ClientMessage.Pass(password))
@@ -86,7 +118,7 @@ class IrcClient(
add(ClientMessage.User(nick, nick)) add(ClientMessage.User(nick, nick))
} }
add(ClientMessage.Cap.END()) add(ClientMessage.Cap.END())
} }.toTypedArray()
queueMessages(*messages.toTypedArray()) queueMessages(*messages)
} }
} }