Skip to content

Commit 5b3a8a1

Browse files
committed
feat: add mapAsync utility and improve player-related API functions
- Introduced `Iterable<E>.mapAsync()` for parallel processing of async transformations. - Enhanced `forEachPlayerInRegion` to support explicit plugin parameter and deprecated inefficient overload. - Added utility methods to convert UUID collections to offline players. - Added deprecation notices for inefficient dispatcher helper methods.
1 parent c47b1ae commit 5b3a8a1

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

surf-api-bukkit/surf-api-bukkit-api/api/surf-api-bukkit-api.api

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,9 @@ public final class dev/slne/surf/surfapi/bukkit/api/util/UtilBukkit {
20432043
public static synthetic fun dispatcher$default (Lorg/bukkit/entity/Entity;Lcom/github/shynixn/mccoroutine/folia/SuspendingPlugin;ILjava/lang/Object;)Lkotlin/coroutines/CoroutineContext;
20442044
public static final fun distanceSqt (Lorg/bukkit/Location;Lorg/bukkit/Location;)D
20452045
public static final fun forEachPlayer (Lkotlin/jvm/functions/Function1;)V
2046+
public static final fun forEachPlayerInRegion (Lcom/github/shynixn/mccoroutine/folia/SuspendingPlugin;Lkotlin/jvm/functions/Function2;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
20462047
public static final fun forEachPlayerInRegion (Lkotlin/jvm/functions/Function2;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
2048+
public static synthetic fun forEachPlayerInRegion$default (Lcom/github/shynixn/mccoroutine/folia/SuspendingPlugin;Lkotlin/jvm/functions/Function2;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
20472049
public static synthetic fun forEachPlayerInRegion$default (Lkotlin/jvm/functions/Function2;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
20482050
public static final fun getCallingPlugin (I)Lorg/bukkit/plugin/java/JavaPlugin;
20492051
public static synthetic fun getCallingPlugin$default (IILjava/lang/Object;)Lorg/bukkit/plugin/java/JavaPlugin;
@@ -2056,6 +2058,8 @@ public final class dev/slne/surf/surfapi/bukkit/api/util/UtilBukkit {
20562058
public static final fun isChunkVisible (Lorg/bukkit/entity/Player;Lorg/bukkit/Location;)Z
20572059
public static final fun isChunkVisible (Lorg/bukkit/entity/Player;Lorg/bukkit/World;II)Z
20582060
public static final fun key (Ljava/lang/String;)Lorg/bukkit/NamespacedKey;
2061+
public static final fun toOfflinePlayers (Ljava/lang/Iterable;)Ljava/util/List;
2062+
public static final fun toOfflinePlayers (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
20592063
public static final fun toPlayers (Ljava/lang/Iterable;)Ljava/util/List;
20602064
public static final fun toPlayers (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
20612065
public static final fun toVector3d (Lorg/bukkit/Location;)Lorg/spongepowered/math/vector/Vector3d;
@@ -5953,6 +5957,7 @@ public final class dev/slne/surf/surfapi/core/api/util/SurfUtil {
59535957
public static final fun getValue (Ljava/lang/ref/WeakReference;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
59545958
public static final fun logIf (Lcom/google/common/flogger/LoggingApi;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)V
59555959
public static final fun logger ()Lcom/google/common/flogger/FluentLogger;
5960+
public static final fun mapAsync (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
59565961
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;B)V
59575962
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;C)V
59585963
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;D)V

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/util/bukkit-util.kt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,27 @@ fun forEachPlayer(action: (player: Player) -> Unit) {
5454
Bukkit.getOnlinePlayers().forEach(action)
5555
}
5656

57+
@Deprecated(
58+
message = "Use the overload with an explicit plugin parameter; this version relies on inefficient stacktrace inspection.",
59+
replaceWith = ReplaceWith("forEachPlayerInRegion(plugin, action, concurrent)")
60+
)
61+
suspend fun forEachPlayerInRegion(
62+
action: suspend (player: Player) -> Unit,
63+
concurrent: Boolean = false,
64+
) = forEachPlayerInRegion(
65+
plugin = getCallingSuspendingPlugin(),
66+
action = action,
67+
concurrent = concurrent,
68+
)
69+
5770
/**
5871
* Executes a suspendable action on each online player, optionally concurrently.
5972
*
6073
* @param action The suspendable action to perform on each player.
6174
* @param concurrent If `true`, actions will run concurrently; otherwise, sequentially. Default is `false`.
6275
*/
6376
suspend fun forEachPlayerInRegion(
77+
plugin: SuspendingPlugin,
6478
action: suspend (player: Player) -> Unit,
6579
concurrent: Boolean = false,
6680
) {
@@ -69,15 +83,15 @@ suspend fun forEachPlayerInRegion(
6983
Bukkit.getOnlinePlayers()
7084
.map {
7185
async {
72-
withContext(it.dispatcher(getCallingSuspendingPlugin())) {
86+
withContext(plugin.entityDispatcher(it)) {
7387
action(it)
7488
}
7589
}
7690
}.awaitAll()
7791
}
7892
} else {
7993
for (player in Bukkit.getOnlinePlayers()) {
80-
withContext(player.dispatcher(getCallingSuspendingPlugin())) {
94+
withContext(plugin.entityDispatcher(player)) {
8195
action(player)
8296
}
8397
}
@@ -124,6 +138,8 @@ fun Location.toVector3d(): Vector3d {
124138
*/
125139
fun Iterable<UUID>.toPlayers() = mapNotNull { Bukkit.getPlayer(it) }
126140

141+
fun Iterable<UUID>.toOfflinePlayers() = mapNotNull { Bukkit.getOfflinePlayer(it) }
142+
127143
/**
128144
* Converts a sequence of UUIDs to a sequence of online [Player] instances.
129145
*
@@ -132,6 +148,8 @@ fun Iterable<UUID>.toPlayers() = mapNotNull { Bukkit.getPlayer(it) }
132148
*/
133149
fun Sequence<UUID>.toPlayers() = mapNotNull { Bukkit.getPlayer(it) }
134150

151+
fun Sequence<UUID>.toOfflinePlayers() = mapNotNull { Bukkit.getOfflinePlayer(it) }
152+
135153
/**
136154
* Checks if the player can see the specified location.
137155
*
@@ -155,7 +173,7 @@ fun Player.isChunkVisible(world: World, chunkX: Int, chunkZ: Int): Boolean {
155173
* @param plugin The suspending plugin instance. Defaults to the calling suspending plugin.
156174
* @return The entity's coroutine dispatcher.
157175
*/
158-
@Deprecated("Stacktrace depth is inefficient")
176+
@Deprecated("Use 'plugin.entityDispatcher(this)' directly instead of relying on this helper, as it uses inefficient stacktrace inspection.")
159177
fun Entity.dispatcher(
160178
plugin: SuspendingPlugin = getCallingSuspendingPlugin(),
161179
) = plugin.entityDispatcher(this)
@@ -167,6 +185,7 @@ fun Entity.dispatcher(
167185
* @param plugin The suspending plugin instance. Defaults to the calling suspending plugin.
168186
* @return The region's coroutine dispatcher.
169187
*/
188+
@Deprecated("Use 'plugin.regionDispatcher(this)' directly instead of relying on this helper, as it uses inefficient stacktrace inspection.")
170189
fun Location.dispatcher(
171190
plugin: SuspendingPlugin = getCallingSuspendingPlugin(),
172191
) = plugin.regionDispatcher(this)
@@ -191,7 +210,7 @@ fun getZFromChunkKey(key: Long): Int {
191210

192211
fun ChunkSnapshot.getHighestBlockYAtBlockCoordinates(
193212
blockX: Int,
194-
blockZ: Int
213+
blockZ: Int,
195214
): Int {
196215
return getHighestBlockYAt(blockX and 15, blockZ and 15)
197216
}

surf-api-core/surf-api-core-api/api/surf-api-core-api.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4328,6 +4328,7 @@ public final class dev/slne/surf/surfapi/core/api/util/SurfUtil {
43284328
public static final fun getValue (Ljava/lang/ref/WeakReference;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
43294329
public static final fun logIf (Lcom/google/common/flogger/LoggingApi;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)V
43304330
public static final fun logger ()Lcom/google/common/flogger/FluentLogger;
4331+
public static final fun mapAsync (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
43314332
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;B)V
43324333
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;C)V
43334334
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;D)V

surf-api-core/surf-api-core-api/src/main/kotlin/dev/slne/surf/surfapi/core/api/util/util.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
1414
import it.unimi.dsi.fastutil.objects.Object2ObjectMap
1515
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps
1616
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
17+
import kotlinx.coroutines.async
18+
import kotlinx.coroutines.awaitAll
19+
import kotlinx.coroutines.coroutineScope
1720
import sun.misc.Unsafe
1821
import java.lang.ref.SoftReference
1922
import java.lang.ref.WeakReference
@@ -382,4 +385,14 @@ operator fun <T> WeakReference<T>.getValue(thisRef: Any?, property: KProperty<*>
382385

383386
operator fun <T> SoftReference<T>.getValue(thisRef: Any?, property: KProperty<*>): T? {
384387
return get()
388+
}
389+
390+
suspend inline fun <E, R> Iterable<E>.mapAsync(crossinline transform: suspend (E) -> R): List<R> {
391+
return coroutineScope {
392+
map { element ->
393+
async {
394+
transform(element)
395+
}
396+
}.awaitAll()
397+
}
385398
}

surf-api-velocity/surf-api-velocity-api/api/surf-api-velocity-api.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,6 +4529,7 @@ public final class dev/slne/surf/surfapi/core/api/util/SurfUtil {
45294529
public static final fun getValue (Ljava/lang/ref/WeakReference;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
45304530
public static final fun logIf (Lcom/google/common/flogger/LoggingApi;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)V
45314531
public static final fun logger ()Lcom/google/common/flogger/FluentLogger;
4532+
public static final fun mapAsync (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
45324533
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;B)V
45334534
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;C)V
45344535
public static final fun setFinalField (Ljava/lang/reflect/Field;Ljava/lang/Object;D)V

0 commit comments

Comments
 (0)