You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/wiki/docs/coroutine.md
+48-28Lines changed: 48 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,16 @@
1
1
# Kotlin Coroutines and Minecraft Plugins
2
2
3
-
When starting with [Coroutines in Kotlin](https://kotlinlang.org/docs/coroutines-basics.html), it is interesting
4
-
how this can be translated to the world of minecraft plugins. It is recommended to learn how Kotlin Coroutines work
5
-
before you continue here.
3
+
When starting with [Coroutines in Kotlin](https://kotlinlang.org/docs/coroutines-basics.html), you may wonder how
4
+
you can use them for minecraft plugins and mods. This guide introduces concepts and a production ready API you can use, to start
5
+
adding coroutines to your project.
6
6
7
7
!!! note "Important"
8
8
Make sure you have already installed MCCoroutine. See [Installation](/gettingstarted) for details.
9
9
10
10
### Starting a coroutine
11
11
12
-
In order to start coroutine You may also encounter the function
13
-
``runBlocking`` because it makes sense for certain scenarios such as unittest.
14
-
However, keep in mind to **avoid** using ``runblocking`` in any of your plugins.
12
+
In order to start a coroutine, you can use the provided ``plugin.launch {}`` extension method. This is safe to be called
13
+
anywhere in your plugin except in onDisable where you need to use ``runBlocking``. However, keep in mind to **avoid** using ``runblocking`` anywhere else in any of your plugins.
15
14
16
15
* To enter a coroutine **anywhere** in your code at any time:
17
16
@@ -62,29 +61,45 @@ However, keep in mind to **avoid** using ``runblocking`` in any of your plugins.
62
61
63
62
=== "Folia"
64
63
65
-
As Folia brings multithreading to Paper based servers, threading becomes more complicated and MCCoroutine requires you to think
66
-
everytime you call plugin.launch. In Bukkit based servers, MCCoroutine can assume the correct thread automatically and optimise ticking. (e.g.
67
-
not sending a task to the scheduler if you are already on the main thread).
68
-
69
-
In Folia, there are many threadpools (explained below) and we do not have a main thread.
64
+
As Folia brings multithreading to Paper based servers, threading becomes a lore more complicated for plugin developers.
70
65
71
66
!!! note "Important"
72
67
You can run mccoroutine-folia in standard Bukkit servers as well. MCCoroutine automatically falls back to the standard Bukkit
73
68
scheduler if the Folia schedulers are not found and the rules for mccoroutine-bukkit start to apply.
69
+
70
+
!!! note "Important"
71
+
If you have been using mccoroutine for Bukkit before, you have to perform some restructuring in your plugin. **Simply changing the imports is not enough.**
72
+
``plugin.launch {}`` works differently in Folia compared to Bukkit.
73
+
74
+
First, it is important to understand that Folia does not have a server main thread. In order to access minecraft resources you need to use the correct thread for
75
+
a given resource. For an entity, you need to use the currently assigned thread for that entity. MCCoroutine provides dispatchers for each of these usecases and
76
+
automatically falls back to the matching dispatchers if you are on a Bukkit server instead of a Folia server.
77
+
78
+
However, this does not solve the problem of accessing our own data in our plugins. We do not have a main thread, so we could try accessing our data on the incoming
79
+
thread. However, sometimes you have to make sure only 1 thread is accessing a resource at a time. This is important for ordering events and avoiding concurrency exceptions.
80
+
Concurrent collections can help with that but you may still need synchronize access in other places.
81
+
82
+
As a solution, MCCoroutine proposes that each plugin gets their own "main thread" and corresponding "mainDispatcher". It is intended to execute all the stuff the plugin is going to do.
83
+
For minecraft actions, like teleporting a player or manipulating an entity. You simply excute them in a sub context and return back to your personal main thread. This
// The plugin.entityDispatcher(entity) parameter ensures, that we end up on the scheduler for the entity in the specific region if we suspend
81
-
// inside the plugin.launch scope. (e.g. using delay)
82
-
// The CoroutineStart.UNDISPATCHED ensures, that we enter plugin.launch scope without any delay on the current thread.
83
-
// You are responsible to ensure that you are on the correct thread pool (in this case the thread pool for the entity), if you pass CoroutineStart.UNDISPATCHED.
84
-
// This is automatically the case if you use plugin.launch{} in events or commands. You can simply use CoroutineStart.UNDISPATCHED here.
85
-
// If you use CoroutineStart.DEFAULT, the plugin.launch scope is entered in the next scheduler tick.
0 commit comments