Skip to content

Commit 943d942

Browse files
committed
ActionInfo interface and PostActionHandler class to reduce duplicate code
1 parent 280e92e commit 943d942

File tree

11 files changed

+123
-134
lines changed

11 files changed

+123
-134
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2025 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.interaction.request
19+
20+
import com.lambda.interaction.construction.context.BuildContext
21+
22+
interface ActionInfo {
23+
val context: BuildContext
24+
val pendingInteractionsList: MutableCollection<BuildContext>
25+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 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.interaction.request
19+
20+
import com.lambda.config.groups.BuildConfig
21+
import com.lambda.event.events.ConnectionEvent
22+
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
23+
import com.lambda.interaction.request.breaking.BrokenBlockHandler
24+
import com.lambda.util.collections.LimitedDecayQueue
25+
26+
abstract class PostActionHandler<T : ActionInfo> {
27+
abstract val pendingActions: LimitedDecayQueue<T>
28+
29+
init {
30+
listenUnsafe<ConnectionEvent.Connect.Pre>(priority = Int.MIN_VALUE) {
31+
pendingActions.clear()
32+
}
33+
}
34+
35+
fun T.startPending() {
36+
pendingActions.add(this)
37+
pendingInteractionsList.add(context)
38+
}
39+
40+
fun T.stopPending() {
41+
pendingActions.remove(this)
42+
pendingInteractionsList.remove(context)
43+
}
44+
45+
fun setPendingConfigs(build: BuildConfig) {
46+
BrokenBlockHandler.pendingActions.setSizeLimit(build.breaking.maxPendingBreaks)
47+
BrokenBlockHandler.pendingActions.setDecayTime(build.interactionTimeout * 50L)
48+
}
49+
}

common/src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.interaction.request.breaking
1919

2020
import com.lambda.interaction.construction.context.BreakContext
21+
import com.lambda.interaction.request.ActionInfo
2122
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
2223
import net.minecraft.client.network.ClientPlayerEntity
2324
import net.minecraft.client.network.ClientPlayerInteractionManager
@@ -28,14 +29,13 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
2829
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action
2930

3031
data class BreakInfo(
31-
var context: BreakContext,
32+
override var context: BreakContext,
3233
var type: BreakType,
3334
var request: BreakRequest
34-
) {
35+
) : ActionInfo {
3536
val breakConfig get() = request.build.breaking
36-
val pendingInteractions get() = request.pendingInteractions
37+
override val pendingInteractionsList get() = request.pendingInteractions
3738

38-
var activeAge = 0
3939
var updatedThisTick = true
4040
var updatedProgressThisTick = false
4141

@@ -82,7 +82,6 @@ data class BreakInfo(
8282
}
8383

8484
fun tickStats() {
85-
activeAge++
8685
updatedThisTick = false
8786
updatedProgressThisTick = false
8887
}

common/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import com.lambda.interaction.request.breaking.BreakManager.processRequest
4848
import com.lambda.interaction.request.breaking.BreakType.Primary
4949
import com.lambda.interaction.request.breaking.BreakType.ReBreak
5050
import com.lambda.interaction.request.breaking.BrokenBlockHandler.destroyBlock
51-
import com.lambda.interaction.request.breaking.BrokenBlockHandler.pendingBreaks
51+
import com.lambda.interaction.request.breaking.BrokenBlockHandler.pendingActions
5252
import com.lambda.interaction.request.breaking.BrokenBlockHandler.setPendingConfigs
5353
import com.lambda.interaction.request.breaking.BrokenBlockHandler.startPending
5454
import com.lambda.interaction.request.interacting.InteractionManager
@@ -98,9 +98,9 @@ object BreakManager : RequestHandler<BreakRequest>(
9898
set(value) { breakInfos[1] = value }
9999
private val breakInfos = arrayOfNulls<BreakInfo>(2)
100100

101-
private val pendingBreakCount get() = breakInfos.count { it != null } + pendingBreaks.size
101+
private val pendingBreakCount get() = breakInfos.count { it != null } + pendingActions.size
102102
override val blockedPositions
103-
get() = breakInfos.mapNotNull { it?.context?.blockPos } + pendingBreaks.map { it.context.blockPos }
103+
get() = breakInfos.mapNotNull { it?.context?.blockPos } + pendingActions.map { it.context.blockPos }
104104

105105
private var activeRequest: BreakRequest? = null
106106

@@ -283,7 +283,7 @@ object BreakManager : RequestHandler<BreakRequest>(
283283
* @see updateBreakProgress
284284
*/
285285
private fun SafeContext.processRequest(breakRequest: BreakRequest?) {
286-
pendingBreaks.cleanUp()
286+
pendingActions.cleanUp()
287287

288288
repeat(2) {
289289
breakRequest?.let { request ->
@@ -486,7 +486,7 @@ object BreakManager : RequestHandler<BreakRequest>(
486486
}
487487

488488
primaryBreak = breakInfo
489-
setPendingConfigs(request)
489+
setPendingConfigs(request.build)
490490
return primaryBreak
491491
}
492492

common/src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ package com.lambda.interaction.request.breaking
1919

2020
import com.lambda.Lambda.mc
2121
import com.lambda.context.SafeContext
22-
import com.lambda.event.events.ConnectionEvent
2322
import com.lambda.event.events.EntityEvent
2423
import com.lambda.event.events.WorldEvent
2524
import com.lambda.event.listener.SafeListener.Companion.listen
26-
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
2725
import com.lambda.interaction.construction.processing.ProcessorRegistry
26+
import com.lambda.interaction.request.PostActionHandler
2827
import com.lambda.interaction.request.breaking.BreakConfig.BreakConfirmationMode
2928
import com.lambda.interaction.request.breaking.BreakManager.lastPosStarted
3029
import com.lambda.interaction.request.breaking.BreakManager.matchesBlockItem
@@ -35,7 +34,6 @@ import com.lambda.util.BlockUtils.fluidState
3534
import com.lambda.util.BlockUtils.isEmpty
3635
import com.lambda.util.BlockUtils.isNotBroken
3736
import com.lambda.util.BlockUtils.matches
38-
import com.lambda.util.Communication.info
3937
import com.lambda.util.Communication.warn
4038
import com.lambda.util.collections.LimitedDecayQueue
4139
import com.lambda.util.player.gamemode
@@ -49,8 +47,8 @@ import net.minecraft.util.math.ChunkSectionPos
4947
*
5048
* @see BreakManager
5149
*/
52-
object BrokenBlockHandler {
53-
val pendingBreaks = LimitedDecayQueue<BreakInfo>(
50+
object BrokenBlockHandler : PostActionHandler<BreakInfo>() {
51+
override val pendingActions = LimitedDecayQueue<BreakInfo>(
5452
TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
5553
) { info ->
5654
mc.world?.let { world ->
@@ -66,13 +64,13 @@ object BrokenBlockHandler {
6664
}
6765
}
6866
info.request.onCancel?.invoke(info.context.blockPos)
69-
info.pendingInteractions.remove(info.context)
67+
info.pendingInteractionsList.remove(info.context)
7068
}
7169

7270
init {
73-
listen<WorldEvent.BlockUpdate.Server>(priority = Int.MIN_VALUE + 1) { event ->
71+
listen<WorldEvent.BlockUpdate.Server>(priority = Int.MIN_VALUE) { event ->
7472
run {
75-
pendingBreaks.firstOrNull { it.context.blockPos == event.pos }
73+
pendingActions.firstOrNull { it.context.blockPos == event.pos }
7674
?: if (reBreak?.context?.blockPos == event.pos) reBreak
7775
else null
7876
}?.let { pending ->
@@ -109,10 +107,10 @@ object BrokenBlockHandler {
109107
}
110108
}
111109

112-
listen<EntityEvent.Update>(priority = Int.MIN_VALUE + 1) {
110+
listen<EntityEvent.Update>(priority = Int.MIN_VALUE) {
113111
if (it.entity !is ItemEntity) return@listen
114112
run {
115-
pendingBreaks.firstOrNull { info -> matchesBlockItem(info, it.entity) }
113+
pendingActions.firstOrNull { info -> matchesBlockItem(info, it.entity) }
116114
?: reBreak?.let { info ->
117115
return@run if (matchesBlockItem(info, it.entity)) info
118116
else null
@@ -128,37 +126,6 @@ object BrokenBlockHandler {
128126
return@listen
129127
}
130128
}
131-
132-
listenUnsafe<ConnectionEvent.Connect.Pre>(priority = Int.MIN_VALUE + 1) {
133-
pendingBreaks.clear()
134-
}
135-
}
136-
137-
/**
138-
* Adds the [info] to the [BrokenBlockHandler], and requesters, pending interaction collections.
139-
*/
140-
fun BreakInfo.startPending() {
141-
pendingBreaks.add(this)
142-
pendingInteractions.add(context)
143-
}
144-
145-
/**
146-
* Removes the [info] from the [BrokenBlockHandler], and requesters, pending interaction collections.
147-
*/
148-
fun BreakInfo.stopPending() {
149-
if (!isReBreaking) {
150-
pendingBreaks.remove(this)
151-
pendingInteractions.remove(context)
152-
}
153-
}
154-
155-
/**
156-
* Sets the size limit and decay time for the [pendingBreaks] [LimitedDecayQueue]
157-
* using the [request]'s configs
158-
*/
159-
fun setPendingConfigs(request: BreakRequest) {
160-
pendingBreaks.setSizeLimit(request.build.breaking.maxPendingBreaks)
161-
pendingBreaks.setDecayTime(request.build.interactionTimeout * 50L)
162129
}
163130

164131
/**

common/src/main/kotlin/com/lambda/interaction/request/interacting/InteractedBlockHandler.kt

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ package com.lambda.interaction.request.interacting
1919

2020
import com.lambda.Lambda.mc
2121
import com.lambda.config.groups.InteractionConfig
22-
import com.lambda.event.events.ConnectionEvent
2322
import com.lambda.event.events.WorldEvent
2423
import com.lambda.event.listener.SafeListener.Companion.listen
25-
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
24+
import com.lambda.interaction.request.PostActionHandler
2625
import com.lambda.module.modules.client.TaskFlowModule
2726
import com.lambda.util.BlockUtils.matches
2827
import com.lambda.util.Communication.info
@@ -32,8 +31,8 @@ import net.minecraft.block.BlockState
3231
import net.minecraft.util.Hand
3332
import net.minecraft.util.math.BlockPos
3433

35-
object InteractedBlockHandler {
36-
val pendingInteractions = LimitedDecayQueue<InteractionInfo>(
34+
object InteractedBlockHandler : PostActionHandler<InteractionInfo>() {
35+
override val pendingActions = LimitedDecayQueue<InteractionInfo>(
3736
TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
3837
) {
3938
info("${it::class.simpleName} at ${it.context.blockPos.toShortString()} timed out")
@@ -45,10 +44,10 @@ object InteractedBlockHandler {
4544

4645
init {
4746
listen<WorldEvent.BlockUpdate.Server>(priority = Int.MIN_VALUE) { event ->
48-
pendingInteractions
47+
pendingActions
4948
.firstOrNull { it.context.blockPos == event.pos }
5049
?.let { info ->
51-
removePendingInteract(info)
50+
info.stopPending()
5251

5352
if (!matchesTargetState(event.pos, info.context.expectedState, event.newState))
5453
return@listen
@@ -59,25 +58,6 @@ object InteractedBlockHandler {
5958
}
6059
}
6160
}
62-
63-
listenUnsafe<ConnectionEvent.Connect.Pre> {
64-
pendingInteractions.clear()
65-
}
66-
}
67-
68-
fun addPendingInteract(info: InteractionInfo) {
69-
pendingInteractions.add(info)
70-
info.pendingInteractionsList.add(info.context)
71-
}
72-
73-
fun removePendingInteract(info: InteractionInfo) {
74-
pendingInteractions.remove(info)
75-
info.pendingInteractionsList.remove(info.context)
76-
}
77-
78-
fun setPendingConfigs(request: InteractionRequest) {
79-
pendingInteractions.setSizeLimit(request.build.maxPendingInteractions)
80-
pendingInteractions.setDecayTime(request.build.interactionTimeout * 50L)
8161
}
8262

8363
private fun matchesTargetState(pos: BlockPos, targetState: BlockState, newState: BlockState) =

common/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionInfo.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ package com.lambda.interaction.request.interacting
2020
import com.lambda.config.groups.InteractionConfig
2121
import com.lambda.interaction.construction.context.BuildContext
2222
import com.lambda.interaction.construction.context.InteractionContext
23+
import com.lambda.interaction.request.ActionInfo
2324

2425
data class InteractionInfo(
25-
val context: InteractionContext,
26-
val pendingInteractionsList: MutableCollection<BuildContext>,
26+
override val context: InteractionContext,
27+
override val pendingInteractionsList: MutableCollection<BuildContext>,
2728
val interact: InteractionConfig
28-
)
29+
) : ActionInfo

common/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionManager.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ import com.lambda.interaction.request.ManagerUtils.isPosBlocked
2929
import com.lambda.interaction.request.PositionBlocking
3030
import com.lambda.interaction.request.RequestHandler
3131
import com.lambda.interaction.request.breaking.BreakManager
32-
import com.lambda.interaction.request.interacting.InteractedBlockHandler.addPendingInteract
33-
import com.lambda.interaction.request.interacting.InteractedBlockHandler.pendingInteractions
32+
import com.lambda.interaction.request.interacting.InteractedBlockHandler.pendingActions
3433
import com.lambda.interaction.request.interacting.InteractedBlockHandler.setPendingConfigs
34+
import com.lambda.interaction.request.interacting.InteractedBlockHandler.startPending
3535
import com.lambda.interaction.request.interacting.InteractionManager.activeRequest
3636
import com.lambda.interaction.request.interacting.InteractionManager.processRequest
3737
import com.lambda.interaction.request.placing.PlaceManager
38-
import com.lambda.interaction.request.placing.PlacedBlockHandler.pendingPlacements
3938
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket
4039
import net.minecraft.util.Hand
4140

@@ -54,7 +53,7 @@ object InteractionManager : RequestHandler<InteractionRequest>(
5453
private var maxInteractionsThisTick = 0
5554

5655
override val blockedPositions
57-
get() = pendingInteractions.map { it.context.blockPos }
56+
get() = pendingActions.map { it.context.blockPos }
5857

5958
init {
6059
listen<TickEvent.Post>(priority = Int.MIN_VALUE) {
@@ -79,7 +78,7 @@ object InteractionManager : RequestHandler<InteractionRequest>(
7978
}
8079

8180
fun SafeContext.processRequest(request: InteractionRequest) {
82-
pendingInteractions.cleanUp()
81+
pendingActions.cleanUp()
8382

8483
if (request.fresh) populateFrom(request)
8584

@@ -94,7 +93,7 @@ object InteractionManager : RequestHandler<InteractionRequest>(
9493
if (!ctx.requestDependencies(request)) return
9594

9695
if (interact.interactConfirmationMode == InteractionConfig.InteractConfirmationMode.None) {
97-
addPendingInteract(InteractionInfo(ctx, request.pendingInteractionsList, interact))
96+
InteractionInfo(ctx, request.pendingInteractionsList, interact).startPending()
9897
}
9998
if (interact.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.AwaitThenInteract) {
10099
interaction.interactBlock(player, Hand.MAIN_HAND, ctx.result)
@@ -110,12 +109,12 @@ object InteractionManager : RequestHandler<InteractionRequest>(
110109
}
111110

112111
private fun populateFrom(request: InteractionRequest) {
113-
setPendingConfigs(request)
112+
setPendingConfigs(request.build)
114113
potentialInteractions = request.contexts
115114
.filter { !isPosBlocked(it.blockPos) }
116115
.toMutableList()
117116

118-
val pendingLimit = (request.build.maxPendingInteractions - pendingPlacements.size).coerceAtLeast(0)
117+
val pendingLimit = (request.build.maxPendingInteractions - pendingActions.size).coerceAtLeast(0)
119118
maxInteractionsThisTick = (request.build.interactionsPerTick.coerceAtMost(pendingLimit))
120119
}
121120

0 commit comments

Comments
 (0)