diff --git a/README.md b/README.md index 205bc8c..e32987c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # KEvent [![Maven Central](https://img.shields.io/maven-central/v/org.rationalityfrontline/kevent.svg?label=maven%20central)](https://search.maven.org/search?q=g:%22org.rationalityfrontline%22%20AND%20a:%22kevent%22) -[![Kotlin 1.5.31](https://img.shields.io/badge/kotlin-1.5.31-blue.svg)](http://kotlinlang.org) +[![Kotlin 1.6.20](https://img.shields.io/badge/kotlin-1.6.20-blue.svg)](http://kotlinlang.org) ![JDK](https://img.shields.io/badge/jdk-%3E%3D11-orange) [![Apache License 2.0](https://img.shields.io/github/license/rationalityfrontline/kevent)](https://github.com/RationalityFrontline/kevent/blob/master/LICENSE) [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) @@ -9,7 +9,7 @@ A powerful in-process event dispatcher based on Kotlin and Coroutines. ## Feature List * Implement publish–subscribe pattern -* Tiny (52.8kb jar) and super-fast (no reflection) +* Tiny (52.2kb jar) and super-fast (no reflection) * Usable in plenty scenarios: plain kotlin, server side, android, javafx, swing * Use Enum as event type, so you don't have to create numerous event classes * Support 3 event dispatch modes with 3 subscriber thread modes @@ -35,7 +35,7 @@ A powerful in-process event dispatcher based on Kotlin and Coroutines. ## Download **Gradle Kotlin DSL** ```kotlin -implementation("org.rationalityfrontline:kevent:2.1.0") +implementation("org.rationalityfrontline:kevent:2.1.1") ``` **Maven** @@ -43,7 +43,7 @@ implementation("org.rationalityfrontline:kevent:2.1.0") org.rationalityfrontline kevent - 2.1.0 + 2.1.1 ``` @@ -60,12 +60,10 @@ private class ExampleSubscriber : KEventSubscriber { println("${"ExampleSubscriber.lambda".padEnd(35)}: $event") } subscribe(EventTypes.STRING_EVENT, ::onStringEvent) - subscribeMultiple( - listOf( - EventTypes.UNIT_EVENT, - EventTypes.STRING_EVENT, - ), ::onAnyEvent - ) + subscribeMultiple(listOf( + EventTypes.UNIT_EVENT, + EventTypes.STRING_EVENT, + ), ::onAnyEvent) } fun unregisterSubscribers() { @@ -167,7 +165,7 @@ JDK: OpenJDK 17+35-2724 64 bit KEvent is released under the [Apache 2.0 license](https://github.com/RationalityFrontline/kevent/blob/master/LICENSE). ```text -Copyright 2020-2021 RationalityFrontline +Copyright 2020-2022 RationalityFrontline Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -180,4 +178,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -``` +``` \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 6410925..064bf13 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,16 @@ -import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.5.31" + kotlin("jvm") version "1.6.20" `java-library` `maven-publish` signing - id("org.jetbrains.dokka") version "1.5.30" - id("org.javamodularity.moduleplugin") version "1.8.8" + id("org.jetbrains.dokka") version "1.6.20" + id("org.javamodularity.moduleplugin") version "1.8.11" } group = "org.rationalityfrontline" -version = "2.1.0" +version = "2.1.1" val NAME = "kevent" val DESC = "A powerful in-process event dispatcher based on Kotlin and Coroutines" val GITHUB_REPO = "RationalityFrontline/kevent" @@ -21,18 +20,19 @@ repositories { } dependencies { - val coroutinesVersion = "1.5.2" + val coroutinesVersion = "1.6.2" /** Kotlin --------------------------------------------------------- */ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:$coroutinesVersion") /** Logging -------------------------------------------------------- */ - implementation("io.github.microutils:kotlin-logging:2.0.11") - val spekVersion = "2.0.17" - /** Logging -------------------------------------------------------- */ - testImplementation("org.slf4j:slf4j-simple:1.7.32") - testImplementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.1.0") - testImplementation("org.jetbrains.kotlin:kotlin-test:${getKotlinPluginVersion()}") + implementation("io.github.microutils:kotlin-logging:2.1.23") + /** Testing -------------------------------------------------------- */ + val spekVersion = "2.0.18" + testImplementation("org.slf4j:slf4j-simple:1.7.36") + testImplementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.3.0") + testImplementation(kotlin("test")) testImplementation("org.spekframework.spek2:spek-dsl-jvm:$spekVersion") testRuntimeOnly("org.spekframework.spek2:spek-runner-junit5:$spekVersion") + testRuntimeOnly(kotlin("reflect")) testRuntimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-swing:$coroutinesVersion") } @@ -101,7 +101,7 @@ publishing { licenses { license { name.set("The Apache Software License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") } } developers { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a2..8049c68 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/org/rationalityfrontline/kevent/KEvent.kt b/src/main/kotlin/org/rationalityfrontline/kevent/KEvent.kt index cb76806..0375e87 100644 --- a/src/main/kotlin/org/rationalityfrontline/kevent/KEvent.kt +++ b/src/main/kotlin/org/rationalityfrontline/kevent/KEvent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 RationalityFrontline + * Copyright 2020-2022 RationalityFrontline * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ package org.rationalityfrontline.kevent import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.consumeAsFlow import mu.KotlinLogging import java.util.* @@ -64,7 +63,7 @@ typealias EventConsumer = (Event) -> Unit * @param consumer event consumer function. * @param threadMode specifies on which thread the subscriber will be called, see [SubscriberThreadMode]. * @param priority subscriber priority, bigger is higher, default to 0. - * @param tag optional tag that is useful for unsubscription, see [KEvent.removeSubscribersByTag]. + * @param tag optional tag that is useful for unsubscribe, see [KEvent.removeSubscribersByTag]. */ data class Subscriber( val eventTypes: Set>, @@ -85,8 +84,8 @@ enum class EventDispatchMode { * Only compatible with [SubscriberThreadMode.POSTING]. * * Usage scenarios: - * * All subscribers of the event type are not time consuming. - * * Subscribers are time consuming but there is no need to call subscribers concurrently and it's ok to block the event posting thread. + * * All subscribers of the event type are not time-consuming. + * * Subscribers are time-consuming but there is no need to call subscribers concurrently and it's ok to block the event posting thread. */ POSTING, @@ -106,7 +105,7 @@ enum class EventDispatchMode { * Only compatible with [SubscriberThreadMode.BACKGROUND]. * * Usage scenarios: - * * Subscribers are time consuming and can be called concurrently. + * * Subscribers are time-consuming and can be called concurrently. */ CONCURRENT, } @@ -121,8 +120,8 @@ enum class SubscriberThreadMode { * Only compatible with [EventDispatchMode.POSTING]. * * Usage scenarios: - * * All subscribers of the event type are not time consuming. - * * Subscribers are time consuming but there is no need to call subscribers concurrently and it's ok to block the event posting thread. + * * All subscribers of the event type are not time-consuming. + * * Subscribers are time-consuming but there is no need to call subscribers concurrently and it's ok to block the event posting thread. */ POSTING, @@ -132,8 +131,8 @@ enum class SubscriberThreadMode { * Only compatible with [EventDispatchMode.CONCURRENT]. * * Usage scenarios: - * * Single time consuming subscriber and the event posting thread must not be blocked (for example, UI thread). - * * Multiple time consuming subscribers and it's ok to run these subscribers concurrently. + * * Single time-consuming subscriber and the event posting thread must not be blocked (for example, UI thread). + * * Multiple time-consuming subscribers and it's ok to run these subscribers concurrently. */ BACKGROUND, @@ -144,7 +143,7 @@ enum class SubscriberThreadMode { * * Usage scenarios: * * The subscriber update UI components and thus must be called in the UI thread - * (this also means the subscriber must not be time consuming). + * (this also means the subscriber must not be time-consuming). * If events are always posted from UI thread, please use [POSTING] for better performance. */ UI, @@ -181,7 +180,7 @@ class KEvent( eventChannel.consumeAsFlow().collect { event -> val subscriberList = subscribersReadOnlyMap[event.type] if (subscriberList == null || subscriberList.isEmpty()) { - if (!event.isSticky) logger.warn { "No subscribers for event type \"${event.type.name}\"" } + if (!event.isSticky) logger.trace { "No subscriber for event type \"${event.type.name}\"" } } else { val e = if (event.isSticky) event.copy(isSticky = false) else event @@ -281,7 +280,7 @@ class KEvent( filter { it.threadMode == SubscriberThreadMode.POSTING } } if (subscriberList == null || subscriberList.isEmpty()) { - logger.warn { "No subscribers for event type \"${event.type.name}\" with dispatch mode ${EventDispatchMode.POSTING}" } + logger.trace { "No subscriber for event type \"${event.type.name}\" with dispatch mode ${EventDispatchMode.POSTING}" } return false } else { subscriberList.forEach { subscriber -> @@ -393,7 +392,7 @@ class KEvent( * @param consumer event consumer function. * @param threadMode thread mode, see [SubscriberThreadMode]. * @param priority priority, bigger is higher. - * @param tag optional tag that is useful for unsubscription, see [KEvent.removeSubscribersByTag]. + * @param tag optional tag that is useful for unsubscribe, see [KEvent.removeSubscribersByTag]. * @return true if subscription is successful, else false. */ fun subscribe( @@ -411,7 +410,7 @@ class KEvent( * @param consumer event consumer function. * @param threadMode thread mode, see [SubscriberThreadMode]. * @param priority priority, bigger is higher. - * @param tag optional tag that is useful for unsubscription, see [KEvent.removeSubscribersByTag]. + * @param tag optional tag that is useful for unsubscribe, see [KEvent.removeSubscribersByTag]. * @return true if subscription is successful, else false. */ fun subscribe( @@ -440,7 +439,7 @@ class KEvent( * @param consumer event consumer function. * @param threadMode thread mode, see [SubscriberThreadMode]. * @param priority priority, bigger is higher. - * @param tag optional tag that is useful for unsubscription, see [KEvent.removeSubscribersByTag]. + * @param tag optional tag that is useful for unsubscribe, see [KEvent.removeSubscribersByTag]. * @return true if subscription is successful, else false. */ fun subscribeMultiple( @@ -459,7 +458,7 @@ class KEvent( * @param consumer event consumer function. * @param threadMode thread mode, see [SubscriberThreadMode]. * @param priority priority, bigger is higher. - * @param tag optional tag that is useful for unsubscription, see [KEvent.removeSubscribersByTag]. + * @param tag optional tag that is useful for unsubscribe, see [KEvent.removeSubscribersByTag]. * @return true if subscription is successful, else false. */ fun subscribeMultiple( @@ -489,7 +488,7 @@ class KEvent( /** * Unsubscribe the subscriber with [eventType] and [consumer]. * - * @return true if subscriber exists and unsubscription is successful, else false. + * @return true if subscriber exists and unsubscribe is successful, else false. */ fun unsubscribe(eventType: Enum<*>, consumer: EventConsumer): Boolean { subscribersMap[eventType]?.run { @@ -506,7 +505,7 @@ class KEvent( /** * Unsubscribe the subscriber with [eventTypes] and [consumer]. * - * @return true if subscriber exists and any of the unsubscription is successful, else false. + * @return true if subscriber exists and all unsubscribe are successful, else false. */ fun unsubscribeMultiple(eventTypes: Collection>, consumer: EventConsumer): Boolean { var removed = false @@ -624,7 +623,7 @@ class KEvent( } /** - * Clear all states of the [KEvent] object. All subscribers, sticky events, event blocking, etc will be removed. + * Clear all states of the [KEvent] object. All subscribers, sticky events, event blocking, etc. will be removed. */ fun clear() { removeAllSubscribers() diff --git a/src/main/kotlin/org/rationalityfrontline/kevent/KEventSubscriber.kt b/src/main/kotlin/org/rationalityfrontline/kevent/KEventSubscriber.kt index 3d4426f..ceada7a 100644 --- a/src/main/kotlin/org/rationalityfrontline/kevent/KEventSubscriber.kt +++ b/src/main/kotlin/org/rationalityfrontline/kevent/KEventSubscriber.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 RationalityFrontline + * Copyright 2020-2022 RationalityFrontline * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,7 +97,7 @@ inline fun KEventSubscriber.subscribeMultiple( /** * Unsubscribe the subscriber with [eventType] and [consumer]. * - * @return true if subscriber exists and unsubscription is successful, else false. + * @return true if subscriber exists and unsubscribe is successful, else false. */ inline fun KEventSubscriber.unsubscribe( eventType: Enum<*>, @@ -107,7 +107,7 @@ inline fun KEventSubscriber.unsubscribe( /** * Unsubscribe the subscriber with [eventTypes] and [consumer]. * - * @return true if subscriber exists and any of the unsubscription is successful, else false. + * @return true if subscriber exists and all unsubscribe are successful, else false. */ inline fun KEventSubscriber.unsubscribeMultiple( eventTypes: Collection>, @@ -117,7 +117,7 @@ inline fun KEventSubscriber.unsubscribeMultiple( /** * Unsubscribe all subscribers with tag of [KEventSubscriber.SUBSCRIBER_TAG]. * - * @return true if subscriber exists and any of the unsubscription is successful, else false. + * @return true if any subscriber gets removed, else false. */ inline fun KEventSubscriber.unsubscribeAll(): Boolean = KEVENT_INSTANCE.removeSubscribersByTag(SUBSCRIBER_TAG) diff --git a/src/test/kotlin/org/rationalityfrontline/kevent/BasicUsageExample.kt b/src/test/kotlin/org/rationalityfrontline/kevent/BasicUsageExample.kt index 3dd1045..ac2a83a 100644 --- a/src/test/kotlin/org/rationalityfrontline/kevent/BasicUsageExample.kt +++ b/src/test/kotlin/org/rationalityfrontline/kevent/BasicUsageExample.kt @@ -11,12 +11,10 @@ private class ExampleSubscriber : KEventSubscriber { println("${"ExampleSubscriber.lambda".padEnd(35)}: $event") } subscribe(EventTypes.STRING_EVENT, ::onStringEvent) - subscribeMultiple( - listOf( - EventTypes.UNIT_EVENT, - EventTypes.STRING_EVENT, - ), ::onAnyEvent - ) + subscribeMultiple(listOf( + EventTypes.UNIT_EVENT, + EventTypes.STRING_EVENT, + ), ::onAnyEvent) } fun unregisterSubscribers() { diff --git a/src/test/kotlin/org/rationalityfrontline/kevent/ThreadingFeature.kt b/src/test/kotlin/org/rationalityfrontline/kevent/ThreadingFeature.kt index be06774..fde2632 100644 --- a/src/test/kotlin/org/rationalityfrontline/kevent/ThreadingFeature.kt +++ b/src/test/kotlin/org/rationalityfrontline/kevent/ThreadingFeature.kt @@ -18,7 +18,7 @@ import kotlin.test.assertTrue object ThreadingFeature : Spek({ - Feature("KEvent supports four event dispatch modes (POSTING, SEQUENTIAL, CONCURRENT, ORDERED_CONCURRENT) and three subscriber thread modes (POSTING, BACKGROUND, UI)") { + Feature("KEvent support three event dispatch modes (POSTING, SEQUENTIAL, CONCURRENT) with three subscriber thread modes (POSTING, BACKGROUND, UI)") { val counter by memoized { AtomicInteger(0) } val calledThreadModesMap by memoized {