Skip to content

Commit 89bcac6

Browse files
committed
Refactor debugger lifecycle, add lifecycle methods to DebugEnvironment
1 parent f31e96b commit 89bcac6

File tree

16 files changed

+387
-143
lines changed

16 files changed

+387
-143
lines changed

Common/src/main/kotlin/gay/object/hexdebug/adapter/DebugAdapter.kt

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import at.petrak.hexcasting.api.casting.math.HexPattern
1010
import gay.`object`.hexdebug.HexDebug
1111
import gay.`object`.hexdebug.adapter.proxy.DebugProxyServerLauncher
1212
import gay.`object`.hexdebug.config.HexDebugServerConfig
13+
import gay.`object`.hexdebug.core.api.debugging.DebugEnvironment
14+
import gay.`object`.hexdebug.core.api.exceptions.IllegalDebugSessionException
15+
import gay.`object`.hexdebug.core.api.exceptions.IllegalDebugThreadException
1316
import gay.`object`.hexdebug.debugger.*
1417
import gay.`object`.hexdebug.items.DebuggerItem
1518
import gay.`object`.hexdebug.items.EvaluatorItem
@@ -39,7 +42,6 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
3942
private var lastDebugger: HexDebugger? = null // for resolving sources after exit
4043
private val debuggers = mutableMapOf<Int, HexDebugger>()
4144
private val threadIds = mutableMapOf<UUID, Int>()
42-
private val restartArgs = mutableMapOf<Int, CastArgs>()
4345
private val state = SharedDebugState()
4446

4547
val launcher: IHexDebugLauncher by lazy {
@@ -48,6 +50,8 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
4850

4951
private val remoteProxy: IDebugProtocolClient get() = launcher.remoteProxy
5052

53+
private val maxThreads get() = HexDebugServerConfig.config.maxDebugThreads(player)
54+
5155
fun isDebugging(threadId: Int) = debugger(threadId) != null
5256

5357
fun debugger(sessionId: UUID) =
@@ -84,28 +88,50 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
8488
).sendToPlayer(player)
8589
}
8690

87-
fun startDebugging(threadId: Int, args: CastArgs, notifyClient: Boolean = true): Boolean {
88-
val threadLimit = if (args.env.isEnlightened) HexDebugServerConfig.config.maxDebugThreads else 1
89-
if (threadId >= threadLimit) return false
91+
fun createDebugThread(debugEnv: DebugEnvironment, maybeThreadId: Int?) {
92+
if (debugEnv.sessionId in threadIds) {
93+
throw IllegalDebugSessionException("Debug session already in use")
94+
}
9095

91-
val debugger = HexDebugger(threadId, state, args)
92-
lastDebugger = debugger
96+
val threadId = resolveThreadId(maybeThreadId)
97+
threadIds[debugEnv.sessionId] = threadId
98+
99+
val debugger = HexDebugger(state, debugEnv, threadId)
93100
debuggers[threadId] = debugger
94-
threadIds[args.debugEnv.sessionId] = threadId
95-
restartArgs[threadId] = args
96101

97102
remoteProxy.thread(ThreadEventArguments().also {
98103
it.reason = ThreadEventArgumentsReason.STARTED
99104
it.threadId = threadId
100105
})
101106

102-
if (notifyClient) {
103-
MsgDebuggerStateS2C(threadId, DebuggerItem.DebugState.DEBUGGING).sendToPlayer(player)
104-
closeEvaluator(threadId)
107+
MsgDebuggerStateS2C(threadId, DebuggerItem.DebugState.DEBUGGING).sendToPlayer(player)
108+
closeEvaluator(threadId)
109+
}
110+
111+
private fun resolveThreadId(threadId: Int?): Int {
112+
if (threadId == null) {
113+
return (0 until maxThreads).firstOrNull { !isDebugging(it) }
114+
?: throw IllegalDebugThreadException("All debug threads are already in use")
105115
}
106116

107-
handleDebuggerStep(threadId, debugger.start())
108-
return true
117+
if (threadId !in (0 until maxThreads)) {
118+
throw IllegalDebugThreadException("Debug thread ID out of range: $threadId")
119+
}
120+
121+
if (isDebugging(threadId)) {
122+
throw IllegalDebugThreadException("Debug thread already in use: $threadId")
123+
}
124+
125+
return threadId
126+
}
127+
128+
fun startExecuting(debugEnv: DebugEnvironment, env: CastingEnvironment, iotas: List<Iota>) {
129+
val debugger = debugger(debugEnv.sessionId)
130+
?: throw IllegalDebugSessionException("Debug session not found")
131+
val result = debugger.startExecuting(env, iotas)
132+
?: throw IllegalDebugSessionException("Debug session is already executing something")
133+
lastDebugger = debugger
134+
handleDebuggerStep(debugger.threadId, result)
109135
}
110136

111137
fun disconnectClient() {
@@ -139,7 +165,7 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
139165

140166
fun evaluate(threadId: Int, env: CastingEnvironment, list: SpellList) =
141167
debugger(threadId)?.let {
142-
val result = it.evaluate(env, list)
168+
val result = it.evaluate(env, list) ?: return null
143169
if (result.startedEvaluating) {
144170
setEvaluatorState(threadId, EvaluatorItem.EvalState.MODIFIED)
145171
}
@@ -158,7 +184,10 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
158184
it.reason = ThreadEventArgumentsReason.EXITED
159185
it.threadId = threadId
160186
})
161-
restartArgs[threadId]?.let { startDebugging(threadId, it) }
187+
debuggers.remove(threadId)?.let {
188+
threadIds.remove(it.sessionId)
189+
it.debugEnv.restart(threadId)
190+
}
162191
}
163192

164193
private fun messageWrapper(consumer: MessageConsumer) = MessageConsumer { message ->
@@ -366,16 +395,22 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
366395
}
367396

368397
override fun pause(args: PauseArguments): CompletableFuture<Void> {
369-
// TODO: wisps/circles?
398+
debugger(args.threadId)?.let {
399+
if (it.state == DebuggerState.RUNNING) {
400+
it.debugEnv.pause()
401+
}
402+
}
370403
return futureOf()
371404
}
372405

373406
override fun restart(args: RestartArguments?): CompletableFuture<Void> {
407+
val envs = debuggers.map { (threadId, debugger) -> threadId to debugger.debugEnv }
408+
374409
debuggers.clear()
375410
threadIds.clear()
376411

377-
for ((threadId, castArgs) in restartArgs) {
378-
startDebugging(threadId, castArgs, false)
412+
for ((threadId, debugEnv) in envs) {
413+
debugEnv.restart(threadId)
379414
}
380415

381416
MsgDebuggerStateS2C(
@@ -446,7 +481,8 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
446481
.map { (threadId, debugger) ->
447482
Thread().apply {
448483
id = threadId
449-
name = "Thread $threadId (${debugger.envType})"
484+
name = "Thread $threadId"
485+
debugger.envName?.let { name += " ($it)" }
450486
}
451487
}
452488
.sortedBy { it.id }

Common/src/main/kotlin/gay/object/hexdebug/config/HexDebugServerConfig.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import dev.architectury.event.events.client.ClientPlayerEvent
55
import dev.architectury.event.events.common.PlayerEvent
66
import gay.`object`.hexdebug.HexDebug
77
import gay.`object`.hexdebug.networking.msg.MsgSyncConfigS2C
8+
import gay.`object`.hexdebug.utils.isEnlightened
89
import me.shedaniel.autoconfig.AutoConfig
910
import me.shedaniel.autoconfig.ConfigData
1011
import me.shedaniel.autoconfig.ConfigHolder
@@ -17,6 +18,7 @@ import me.shedaniel.autoconfig.serializer.PartitioningSerializer
1718
import me.shedaniel.autoconfig.serializer.PartitioningSerializer.GlobalData
1819
import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer
1920
import net.minecraft.network.FriendlyByteBuf
21+
import net.minecraft.server.level.ServerPlayer
2022
import net.minecraft.world.InteractionResult
2123

2224
// we can't use a companion object because GlobalData sees the field and throws an error :/
@@ -95,6 +97,10 @@ object HexDebugServerConfig {
9597
var maxDebugThreads: Int = 4
9698
private set
9799

100+
fun maxDebugThreads(caster: ServerPlayer): Int {
101+
return if (caster.isEnlightened) maxDebugThreads else 1
102+
}
103+
98104
fun encode(buf: FriendlyByteBuf) {
99105
buf.writeInt(maxUndoStackSize)
100106
buf.writeLong(splicingTableMediaCost)

Common/src/main/kotlin/gay/object/hexdebug/debugger/CastArgs.kt

Lines changed: 0 additions & 14 deletions
This file was deleted.

Common/src/main/kotlin/gay/object/hexdebug/debugger/Enums.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package gay.`object`.hexdebug.debugger
22

3+
enum class DebuggerState(val canResume: Boolean) {
4+
RUNNING(canResume = false),
5+
PAUSED(canResume = true),
6+
CAUGHT_MISHAP(canResume = true),
7+
TERMINATED(canResume = false),
8+
}
9+
310
enum class StopReason(val value: String, val stopImmediately: Boolean) {
411
STEP("step", false),
512
BREAKPOINT("breakpoint", true),

0 commit comments

Comments
 (0)