Skip to content

Commit

Permalink
Merge pull request #92 from Shynixn/development
Browse files Browse the repository at this point in the history
Merge changes to Master --release
  • Loading branch information
Shynixn authored Jan 14, 2023
2 parents fc5f59b + c995b5f commit 9076233
Show file tree
Hide file tree
Showing 68 changed files with 1,961 additions and 121 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,27 @@ jobs:
asset_name: MCCoroutine-Velocity-Core.jar
asset_content_type: application/jar

- name: Upload Velocity Sample Plugin to Github
- name: Upload Minestom Api to Github
if: "contains(github.event.head_commit.message, '--release') && contains(github.ref, 'master')"
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: /home/runner/work/MCCoroutine/MCCoroutine/mccoroutine-velocity-sample/build/libs/mccoroutine-velocity-sample-${{ env.RELEASE_VERSION }}.jar
asset_name: MCCoroutine-Velocity-Plugin-Sample.jar
asset_path: /home/runner/work/MCCoroutine/MCCoroutine/mccoroutine-minestom-api/build/libs/mccoroutine-minestom-api-${{ env.RELEASE_VERSION }}.jar
asset_name: MCCoroutine-Minestom-Api.jar
asset_content_type: application/jar

- name: Upload Minestom Core to Github
if: "contains(github.event.head_commit.message, '--release') && contains(github.ref, 'master')"
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: /home/runner/work/MCCoroutine/MCCoroutine/mccoroutine-minestom-core/build/libs/mccoroutine-minestom-core-${{ env.RELEASE_VERSION }}.jar
asset_name: MCCoroutine-Minestom-Core.jar
asset_content_type: application/jar

Documentation:
runs-on: ubuntu-latest
Expand All @@ -217,6 +227,7 @@ jobs:
./gradlew generateSpongeJavaDocPages > /dev/null
./gradlew generateBungeeCordJavaDocPages > /dev/null
./gradlew generateVelocityJavaDocPages > /dev/null
./gradlew generateMinestomJavaDocPages > /dev/null
sudo apt-get install -y mkdocs
pip install mkdocs-material
pip install Pygments
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ local.properties
*.log
*.class
.gradle
build
build
extensions/*
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ the existing APIs with suspendable commands, events and schedules.
* CraftBukkit
* SpongeVanilla
* SpongeForge
* Minestom

**Supported Proxies:**

Expand Down Expand Up @@ -66,6 +67,7 @@ private suspend fun bob() {

* [MCCoroutine JavaDocs for the Bukkit-API](https://shynixn.github.io/MCCoroutine/apidocs/mccoroutine-root/com.github.shynixn.mccoroutine.bukkit/index.html)
* [MCCoroutine JavaDocs for the Sponge-API](https://shynixn.github.io/MCCoroutine/apidocs/mccoroutine-root/com.github.shynixn.mccoroutine.sponge/index.html)
* [MCCoroutine JavaDocs for the Minestom-API](https://shynixn.github.io/MCCoroutine/apidocs/mccoroutine-root/com.github.shynixn.mccoroutine.minestom/index.html)
* [MCCoroutine JavaDocs for the BungeeCord-API](https://shynixn.github.io/MCCoroutine/apidocs/mccoroutine-root/com.github.shynixn.mccoroutine.bungeecord/index.html)
* [MCCoroutine JavaDocs for the Velocity-API](https://shynixn.github.io/MCCoroutine/apidocs/mccoroutine-root/com.github.shynixn.mccoroutine.velocity/index.html)
* [Article on custom frameworks](https://github.com/Shynixn/MCCoroutine/blob/master/ARTICLE.md)
Expand Down
22 changes: 14 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath group: 'org.jetbrains.kotlin', name: 'kotlin-gradle-plugin', version: '1.3.72'
classpath group: 'org.jetbrains.kotlin', name: 'kotlin-gradle-plugin', version: '1.7.10'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.5.31"
}
}
Expand Down Expand Up @@ -43,7 +43,7 @@ tasks.register("printVersion") {

subprojects {
group 'com.github.shynixn.mccoroutine'
version '2.9.0'
version '2.10.0'

sourceCompatibility = 1.8

Expand Down Expand Up @@ -144,12 +144,9 @@ subprojects {
}

dependencies {
testCompile 'org.jetbrains.kotlin:kotlin-test'
testCompile 'org.jetbrains.kotlin:kotlin-test-junit'
testCompile 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testCompile 'org.mockito:mockito-core:2.23.0'

testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testImplementation 'org.mockito:mockito-core:2.23.0'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}
}

Expand Down Expand Up @@ -196,3 +193,12 @@ task generateVelocityJavaDocPages(type: org.jetbrains.dokka.gradle.DokkaTask) {
}
}
}

task generateMinestomJavaDocPages(type: org.jetbrains.dokka.gradle.DokkaTask) {
dokkaSourceSets {
named("main") {
outputDirectory = file("docs/apidocs")
sourceRoots.from(file("mccoroutine-minestom-api/src/main/java"))
}
}
}
1 change: 1 addition & 0 deletions docs/wiki/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ the existing APIs with suspendable commands, events and schedules.
* CraftBukkit
* SpongeVanilla
* SpongeForge
* Minestom

**Supported Proxies:**

Expand Down
38 changes: 36 additions & 2 deletions docs/wiki/docs/commandexecutor.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Suspending Commandexecutors

This page explains how you can use Kotlin Coroutines using the suspend key word for command executors in minecraft plugins.
This page explains how you can use Kotlin Coroutines using the suspend key word for command executors in minecraft
plugins.

## Create the CommandExecutor

Expand Down Expand Up @@ -126,6 +127,34 @@ This page explains how you can use Kotlin Coroutines using the suspend key word

A ``BrigadierCommand`` can be executed asynchronously using the ``executesSuspend`` extension function. More details below.

=== "Minestom"

Create a traditional command and user ``server.launch`` or ``extension.launch`` in the addSyntax handler.

````kotlin
import com.github.shynixn.mccoroutine.minestom.launch
import net.minestom.server.MinecraftServer
import net.minestom.server.command.builder.Command
import net.minestom.server.command.builder.arguments.ArgumentType
import net.minestom.server.entity.Player

class PlayerDataCommandExecutor(private val server: MinecraftServer, private val database: Database) : Command("mycommand") {
init {
val nameArgument = ArgumentType.String("name")
addSyntax({ sender, context ->
server.launch {
if (sender is Player) {
val name : String = context.get(nameArgument)
val playerData = database.getDataFromPlayer(sender)
playerData.name = name
database.saveData(sender, playerData)
}
}
})
}
}
````

## Register the CommandExecutor

=== "Bukkit"
Expand Down Expand Up @@ -284,6 +313,11 @@ This page explains how you can use Kotlin Coroutines using the suspend key word
}
````

=== "Minestom"

Register the command in the same way as a traditional command.

## Test the CommandExecutor

Join your server and use the playerData command to observe ``getDataFromPlayer`` and ``saveData`` messages getting printed to your server log.
Join your server and use the playerData command to observe ``getDataFromPlayer`` and ``saveData`` messages getting
printed to your server log.
128 changes: 107 additions & 21 deletions docs/wiki/docs/coroutine.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,117 @@
# Kotlin Coroutines and Minecraft Plugins

When starting with [Coroutines in Kotlin](https://kotlinlang.org/docs/coroutines-basics.html), it is interesting
how this can be translated to the world of minecraft plugins. It is recommended to learn how Kotlin Coroutines work before you continue here.
how this can be translated to the world of minecraft plugins. It is recommended to learn how Kotlin Coroutines work
before you continue here.

!!! note "Important"
Make sure you have already installed MCCoroutine. See [Installation](/gettingstarted) for details.

### Starting a coroutine

For beginners, it is often confusing how to enter a coroutine. The examples in the official guide mostly use ``runBlocking``
For beginners, it is often confusing how to enter a coroutine. The examples in the official guide mostly
use ``runBlocking``
because it makes sense for testing. However, keep in mind to **avoid** using ``runblocking`` in any of your plugins.

* To enter a coroutine **anywhere** in your code at any time:

```kotlin
fun foo() {
plugin.launch {
// This will always be on the minecraft main thread.
=== "Bukkit"

```kotlin
import com.github.shynixn.mccoroutine.bukkit.launch
import org.bukkit.plugin.Plugin

fun foo() {
plugin.launch {
// This will always be on the minecraft main thread.
}
}
}
```
```

=== "BungeeCord"

```kotlin
import com.github.shynixn.mccoroutine.bungeecord.launch
import net.md_5.bungee.api.plugin.Plugin

fun foo() {
plugin.launch {
// This will be a random thread on the BungeeCord threadpool
}
}
```

=== "Sponge"

```kotlin
import com.github.shynixn.mccoroutine.sponge.launch
import org.spongepowered.api.plugin.PluginContainer

fun foo() {
plugin.launch {
// This will always be on the minecraft main thread.
}
}
```

=== "Velocity"

```kotlin
import com.github.shynixn.mccoroutine.velocity.launch
import com.velocitypowered.api.plugin.PluginContainer

fun foo() {
plugin.launch {
// This will be a random thread on the Velocity threadpool
}
}
```

=== "Minestom"

Minestom has got 2 lifecycle scopes, the server scope and the extension scope.
When this guide talks about a ``plugin``, the corresponding class in Minestom is ``Extension`` or ``MinecraftServer`` depending on your usecase.

Server level (if you are developing a new server):

```kotlin
import com.github.shynixn.mccoroutine.minestom.launch
import net.minestom.server.MinecraftServer

fun foo() {
server.launch {
// This will always be on the minecraft main thread.
}
}
```

Extension level (if you are developing a new extension):

```kotlin
import com.github.shynixn.mccoroutine.minestom.launch
import net.minestom.server.extensions.Extension

fun foo() {
extension.launch {
// This will always be on the minecraft main thread.
}
}
```


### Switching coroutine context

Later in the [Coroutines in Kotlin](https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html) guide, the terms coroutine-context and dispatchers are explained.
A dispatcher determines what thread or threads the corresponding coroutine uses for its execution. Therefore, MCCoroutine offers 2 custom dispatchers:

Later in the [Coroutines in Kotlin](https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html) guide, the terms
coroutine-context and dispatchers are explained.
A dispatcher determines what thread or threads the corresponding coroutine uses for its execution. Therefore,
MCCoroutine offers 2 custom dispatchers:

* minecraftDispatcher (Allows to execute coroutines on the main minecraft thread)
* asyncDispatcher (Allows to execute coroutines on the async minecraft threadpool)

!!! note "Important"
**However, it is highly recommend to use ``Dispatchers.IO`` instead of asyncDispatcher because the scheduling is more accurate.**
**However, it is highly recommend to use ``Dispatchers.IO`` instead of asyncDispatcher because the scheduling is more
accurate.**
Additional technical details can be found here: [GitHub Issue](https://github.com/Shynixn/MCCoroutine/issues/87).

An example how this works is shown below:
Expand Down Expand Up @@ -60,10 +141,13 @@ fun foo() {
}
```

Normally, you do not need to call ``plugin.minecraftDispatcher`` in your code. Instead, you are guaranteed to be always on the minecraft main thread
in the ``plugin.launch{}`` scope and use sub coroutines (e.g. withContext) to perform asynchronous operations. Such a case can be found below:
Normally, you do not need to call ``plugin.minecraftDispatcher`` in your code. Instead, you are guaranteed to be always
on the minecraft main thread
in the ``plugin.launch{}`` scope and use sub coroutines (e.g. withContext) to perform asynchronous operations. Such a
case can be found below:

```kotlin
// This is a Bukkit example, but it works in the same way in every other framework.
@EventHandler
fun onPlayerJoinEvent(event: PlayerJoinEvent) {
plugin.launch {
Expand All @@ -74,7 +158,7 @@ fun onPlayerJoinEvent(event: PlayerJoinEvent) {
val friendNames = Files.readAllLines(Paths.get("$name.txt"))
friendNames
}

// Main Thread
val friendText = listOfFriends.joinToString(", ")
event.player.sendMessage("My friends are: $friendText")
Expand All @@ -88,24 +172,25 @@ fun onPlayerJoinEvent(event: PlayerJoinEvent) {
If you use ``plugin.launch``, it is important to understand the execution order.

````kotlin
class Foo(private val plugin : Plugin) {
// This is a Bukkit example, but it works in the same way in every other framework.
class Foo(private val plugin: Plugin) {

fun bar() {
// Main Thread
println("I am first")

val job = plugin.launch {
println("I am second") // The context is not suspended when switching to the same suspendable context.
delay(1000)
println("I am fourth") // The context is given back after 1000 milliseconds and continuous here.
bob()
}

// When calling delay the suspendable context is suspended and the original context immediately continuous here.
println("I am third")
}

private suspend fun bob(){
private suspend fun bob() {
println("I am fifth")
}
}
Expand All @@ -119,9 +204,10 @@ class Foo(private val plugin : Plugin) {
"I am fifth"
````

### Coroutines everywhere
### Coroutines everywhere

Using ``plugin.launch{}``is valuable if you migrate existing plugins to use coroutines. However, if you write a new plugin from scratch, you may consider using
Using ``plugin.launch{}``is valuable if you migrate existing plugins to use coroutines. However, if you write a new
plugin from scratch, you may consider using
convenience integrations provided by MCCoroutine such as:

* Suspending Plugin
Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/docs/exception.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ logger.log(
You can handle exceptions by yourself by listening to the ``MCCoroutineExceptionEvent``. This event is sent to the event bus of the minecraft frame work (e.g. Bukkit, Sponge, BungeeCord)
and can be used for logging. The following points should be considered:

* The event arrives at the main thread (Bukkit, Sponge)
* The event arrives at the main thread (Bukkit, Sponge, Minestom)
* The event is also called for ``CoroutineCancellation``
* Exceptions arrive for every plugin using MCCoroutine. Check if ``event.plugin`` equals your plugin.
* You can cancel the event to disable logging the event with the default exception behaviour
Expand Down
Loading

0 comments on commit 9076233

Please sign in to comment.