Skip to content

Commit 51fade3

Browse files
authored
module priority (#220)
1 parent d56f5ef commit 51fade3

37 files changed

+323
-223
lines changed

src/main/java/com/lambda/mixin/MinecraftClientMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void onNetwork(ClientPlayerInteractionManager instance, Operation<Void> original
9696

9797
@Definition(id = "overlay", field = "Lnet/minecraft/client/MinecraftClient;overlay:Lnet/minecraft/client/gui/screen/Overlay;")
9898
@Expression("this.overlay == null")
99-
@ModifyExpressionValue(method = "tick", at = @At("MIXINEXTRAS:EXPRESSION"))
99+
@ModifyExpressionValue(method = "tick", at = @At(value = "MIXINEXTRAS:EXPRESSION", ordinal = 1))
100100
private boolean modifyCurrentScreenNullCheck(boolean original) {
101101
if (!original || this.currentScreen != null) {
102102
EventFlow.post(TickEvent.Input.Pre.INSTANCE);

src/main/kotlin/com/lambda/Lambda.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ package com.lambda
1919

2020
import com.google.gson.Gson
2121
import com.google.gson.GsonBuilder
22-
import com.lambda.config.serializer.BlockPosCodec
2322
import com.lambda.config.serializer.BlockCodec
23+
import com.lambda.config.serializer.BlockPosCodec
2424
import com.lambda.config.serializer.ColorSerializer
2525
import com.lambda.config.serializer.GameProfileCodec
2626
import com.lambda.config.serializer.ItemCodec
@@ -45,7 +45,6 @@ import net.minecraft.item.Item
4545
import net.minecraft.item.ItemStack
4646
import net.minecraft.item.PotionItem
4747
import net.minecraft.item.RangedWeaponItem
48-
import net.minecraft.registry.DynamicRegistryManager
4948
import net.minecraft.text.Text
5049
import net.minecraft.util.math.BlockPos
5150
import org.apache.logging.log4j.LogManager
@@ -92,7 +91,7 @@ object Lambda : ClientModInitializer {
9291

9392
init {
9493
// We want the opengl context to be created
95-
listenOnceUnsafe<ClientEvent.Startup>(priority = Int.MAX_VALUE) {
94+
listenOnceUnsafe<ClientEvent.Startup>({ Int.MAX_VALUE }) {
9695
LOG.info("$MOD_NAME $VERSION initialized in ${Loader.initialize()} ms\n")
9796
if (ClickGuiLayout.setLambdaWindowIcon) setLambdaWindowIcon()
9897
true

src/main/kotlin/com/lambda/config/AutomationConfig.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,16 @@ open class AutomationConfig(
5858

5959
companion object {
6060
context(module: Module)
61-
fun MutableAutomationConfig.setDefaultAutomationConfig(
62-
name: String = module.name,
63-
edits: (AutomationConfig.() -> Unit)? = null
61+
fun IMutableAutomationConfig.setDefaultAutomationConfig(
62+
name: String = module.name,
63+
edits: (AutomationConfig.() -> Unit)? = null
6464
) {
6565
this.defaultAutomationConfig = AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
6666
}
6767

68-
fun MutableAutomationConfig.setDefaultAutomationConfig(
69-
name: String,
70-
edits: (AutomationConfig.() -> Unit)? = null
68+
fun IMutableAutomationConfig.setDefaultAutomationConfig(
69+
name: String,
70+
edits: (AutomationConfig.() -> Unit)? = null
7171
) {
7272
defaultAutomationConfig = AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
7373
}

src/main/kotlin/com/lambda/config/Configuration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ abstract class Configuration : Jsonable, Loadable {
6565
get() = File("${primary.parent}/${primary.nameWithoutExtension}-backup.${primary.extension}")
6666

6767
override fun load(): String {
68-
listenUnsafe<ClientEvent.Shutdown>(Int.MIN_VALUE) { trySave() }
68+
listenUnsafe<ClientEvent.Shutdown>({ Int.MIN_VALUE }) { trySave() }
6969
register()
7070
return super.load()
7171
}

src/main/kotlin/com/lambda/config/MutableAutomationConfig.kt renamed to src/main/kotlin/com/lambda/config/IMutableAutomationConfig.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import com.lambda.interaction.managers.interacting.InteractConfig
2626
import com.lambda.interaction.managers.inventory.InventoryConfig
2727
import com.lambda.interaction.managers.rotating.RotationConfig
2828

29-
interface MutableAutomationConfig : Automated {
29+
interface IMutableAutomationConfig : Automated {
3030
var defaultAutomationConfig: AutomationConfig
3131
var backingAutomationConfig: AutomationConfig
3232
var automationConfig: AutomationConfig
@@ -40,7 +40,7 @@ interface MutableAutomationConfig : Automated {
4040
override val eatConfig: EatConfig get() = automationConfig.eatConfig
4141
}
4242

43-
class MutableAutomationConfigImpl : MutableAutomationConfig {
43+
class MutableAutomationConfig : IMutableAutomationConfig {
4444
override var defaultAutomationConfig: AutomationConfig = AutomationConfig.Companion.DEFAULT
4545
set(value) {
4646
field = value

src/main/kotlin/com/lambda/config/UserAutomationConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import com.lambda.module.Module
2424
import com.lambda.module.ModuleRegistry.moduleNameMap
2525

2626
class UserAutomationConfig(override val name: String) : AutomationConfig(name, UserAutomationConfigs) {
27-
val linkedModules = setting<String>("Linked Modules", emptySet(), moduleNameMap.filter { it.value.defaultAutomationConfig != Companion.DEFAULT }.keys)
27+
val linkedModules = setting<String>("Linked Modules", emptySet(), moduleNameMap.filter { it.value.defaultAutomationConfig != Companion.DEFAULT }.keys) { false }
2828
.onSelect { name ->
2929
moduleNameMap[name]?.let {
3030
it.removeLink()

src/main/kotlin/com/lambda/event/EventFlow.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,17 @@ object EventFlow {
9797
concurrentListeners.unsubscribe(this)
9898
}
9999

100+
fun Any.updateListenerSorting() {
101+
syncListeners.updateListenerSorting(this)
102+
concurrentListeners.updateListenerSorting(this)
103+
}
104+
105+
private fun Subscriber.updateListenerSorting(owner: Any) =
106+
values.forEach { listeners ->
107+
val matching = listeners.filter { it.owner === owner }
108+
matching.forEach { listeners.remove(it); it.priority.update(); listeners.add(it) }
109+
}
110+
100111
init {
101112
// parallel event execution on dedicated threads
102113
runConcurrent {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2026 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.event
19+
20+
interface OwnerPriority {
21+
val ownerPriority: Int
22+
}

src/main/kotlin/com/lambda/event/listener/Listener.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ package com.lambda.event.listener
2020
import com.lambda.event.Event
2121
import com.lambda.event.EventFlow
2222
import com.lambda.event.Muteable
23+
import com.lambda.event.OwnerPriority
2324
import com.lambda.module.Module
25+
import com.lambda.util.collections.Updatable
2426

2527
/**
2628
* An abstract class representing a [Listener] in the [Event] system ([EventFlow]).
@@ -45,7 +47,7 @@ import com.lambda.module.Module
4547
* @property alwaysListen If true, the [Listener] will always be triggered, even if the [owner] is [Muteable.isMuted].
4648
*/
4749
abstract class Listener<T : Event> : Comparable<Listener<T>> {
48-
abstract val priority: Int
50+
abstract val priority: Updatable<Int>
4951
abstract val owner: Any
5052
abstract val alwaysListen: Boolean
5153

@@ -61,10 +63,13 @@ abstract class Listener<T : Event> : Comparable<Listener<T>> {
6163

6264
companion object {
6365
val comparator = compareBy<Listener<out Event>> {
64-
it.priority
66+
it.priority.value
6567
}.thenBy {
6668
// Hashcode is needed because ConcurrentSkipListSet handles insertion based on compareTo
6769
it.hashCode()
6870
}
71+
72+
val Any.ownerPriorityOr0Getter
73+
get() = (this as? OwnerPriority)?.let { { ownerPriority } } ?: { 0 }
6974
}
7075
}

src/main/kotlin/com/lambda/event/listener/SafeListener.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.lambda.threading.runConcurrent
2525
import com.lambda.threading.runGameScheduled
2626
import com.lambda.threading.runSafe
2727
import com.lambda.util.Pointer
28+
import com.lambda.util.collections.updatable
2829
import com.lambda.util.selfReference
2930
import kotlinx.coroutines.CoroutineDispatcher
3031
import kotlinx.coroutines.Dispatchers
@@ -62,11 +63,13 @@ import kotlin.reflect.KProperty
6263
* @property function The function to be executed when the event occurs. This function operates within a [SafeContext].
6364
*/
6465
class SafeListener<T : Event>(
65-
override val priority: Int = 0,
66+
priorityProvider: () -> Int,
6667
override val owner: Any,
6768
override val alwaysListen: Boolean = false,
6869
val function: SafeContext.(T) -> Unit
6970
) : Listener<T>(), ReadOnlyProperty<Any?, T?> {
71+
override val priority = updatable(priorityProvider)
72+
7073
/**
7174
* The last processed event signal.
7275
*/
@@ -118,7 +121,7 @@ class SafeListener<T : Event>(
118121
* @return The newly created and registered [SafeListener].
119122
*/
120123
inline fun <reified T : Event> Any.listen(
121-
priority: Int = 0,
124+
noinline priority: () -> Int = ownerPriorityOr0Getter,
122125
alwaysListen: Boolean = false,
123126
noinline function: SafeContext.(T) -> Unit = {}
124127
): SafeListener<T> {
@@ -163,7 +166,7 @@ class SafeListener<T : Event>(
163166
*/
164167
fun <T : Event> Any.listen(
165168
kClass: KClass<out T>,
166-
priority: Int = 0,
169+
priority: () -> Int = ownerPriorityOr0Getter,
167170
alwaysListen: Boolean = false,
168171
function: SafeContext.(T) -> Unit = {},
169172
): SafeListener<T> {
@@ -205,7 +208,7 @@ class SafeListener<T : Event>(
205208
* @return The newly created and registered [SafeListener].
206209
*/
207210
inline fun <reified T : Event> Any.listenOnce(
208-
priority: Int = 0,
211+
noinline priority: () -> Int = ownerPriorityOr0Getter,
209212
alwaysListen: Boolean = false,
210213
noinline predicate: SafeContext.(T) -> Boolean = { true },
211214
): ReadWriteProperty<Any?, T?> {
@@ -253,7 +256,7 @@ class SafeListener<T : Event>(
253256
* @return The newly created and registered [SafeListener].
254257
*/
255258
inline fun <reified T : Event> Any.listenConcurrently(
256-
priority: Int = 0,
259+
noinline priority: () -> Int = ownerPriorityOr0Getter,
257260
alwaysListen: Boolean = false,
258261
scheduler: CoroutineDispatcher = Dispatchers.Default,
259262
noinline function: suspend SafeContext.(T) -> Unit = {},

0 commit comments

Comments
 (0)