Skip to content

Commit 949e04e

Browse files
committed
Merge branch 'main' into 1.19
2 parents ef6a016 + 1303998 commit 949e04e

24 files changed

+396
-219
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
88

99
### Changed
1010

11+
- The Debugger can now be used without VSCode being connected! The next evaluated iota is displayed above the hotbar each time the debugger stops (configurable).
1112
- A message is now displayed if attempting to use an Evaluator when not debugging, instead of silently failing.
1213
- Evaluators are now prevented from evaluating patterns after an Uncaught Mishap breakpoint is hit.
1314

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

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import at.petrak.hexcasting.api.spell.math.HexPattern
1010
import at.petrak.hexcasting.common.network.MsgNewSpellPatternAck
1111
import at.petrak.hexcasting.xplat.IXplatAbstractions
1212
import gay.`object`.hexdebug.HexDebug
13-
import gay.`object`.hexdebug.adapter.DebugAdapterState.*
13+
import gay.`object`.hexdebug.adapter.DebugAdapterState.Debugging
14+
import gay.`object`.hexdebug.adapter.DebugAdapterState.NotDebugging
1415
import gay.`object`.hexdebug.adapter.proxy.DebugProxyServerLauncher
1516
import gay.`object`.hexdebug.debugger.*
1617
import gay.`object`.hexdebug.items.ItemDebugger
1718
import gay.`object`.hexdebug.items.ItemEvaluator
18-
import gay.`object`.hexdebug.networking.HexDebugNetworking
19-
import gay.`object`.hexdebug.networking.MsgDebuggerStateS2C
20-
import gay.`object`.hexdebug.networking.MsgEvaluatorStateS2C
19+
import gay.`object`.hexdebug.networking.msg.MsgDebuggerStateS2C
20+
import gay.`object`.hexdebug.networking.msg.MsgEvaluatorStateS2C
21+
import gay.`object`.hexdebug.networking.msg.MsgPrintDebuggerStatusS2C
2122
import gay.`object`.hexdebug.utils.futureOf
2223
import gay.`object`.hexdebug.utils.paginate
2324
import gay.`object`.hexdebug.utils.toFuture
@@ -36,16 +37,14 @@ import java.util.concurrent.CompletableFuture
3637
import java.util.concurrent.CompletionException
3738

3839
open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
39-
private var state: DebugAdapterState = NotConnected
40+
private var state: DebugAdapterState = NotDebugging()
4041
set(value) {
4142
field = value
4243
setDebuggerState(value)
4344
}
4445

4546
val isDebugging get() = state is Debugging
4647

47-
val canStartDebugging get() = state is ReadyToDebug
48-
4948
val debugger get() = (state as? Debugging)?.debugger
5049

5150
open val launcher: IHexDebugLauncher by lazy {
@@ -62,7 +61,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
6261
)
6362

6463
protected open fun setDebuggerState(debuggerState: ItemDebugger.DebugState) {
65-
HexDebugNetworking.sendToPlayer(player, MsgDebuggerStateS2C(debuggerState))
64+
MsgDebuggerStateS2C(debuggerState).sendToPlayer(player)
6665

6766
// close the debugger grid if we stopped debugging
6867
if (debuggerState == ItemDebugger.DebugState.NOT_DEBUGGING) {
@@ -72,21 +71,29 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
7271
}
7372

7473
protected open fun setEvaluatorState(evalState: ItemEvaluator.EvalState) {
75-
HexDebugNetworking.sendToPlayer(player, MsgEvaluatorStateS2C(evalState))
74+
MsgEvaluatorStateS2C(evalState).sendToPlayer(player)
75+
}
76+
77+
protected open fun printDebuggerStatus(iota: String, index: Int) {
78+
MsgPrintDebuggerStatusS2C(
79+
iota = iota,
80+
index = index,
81+
line = state.initArgs.indexToLine(index),
82+
isConnected = state.isConnected,
83+
).sendToPlayer(player)
7684
}
7785

7886
fun startDebugging(args: CastArgs): Boolean {
79-
val state = state as? NotDebugging ?: return false
80-
this.state = Debugging(state, args)
81-
remoteProxy.initialized()
87+
if (state is Debugging) return false
88+
val state = Debugging(state, args).also { state = it }
89+
handleDebuggerStep(state.debugger.start())
8290
return true
8391
}
8492

8593
fun disconnectClient() {
86-
if (state !is NotConnected) {
94+
if (state.isConnected) {
8795
remoteProxy.terminated(TerminatedEventArguments())
88-
89-
state = NotConnected
96+
state.isConnected = false
9097
}
9198
}
9299

@@ -99,11 +106,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
99106
it.category = category
100107
it.output = value
101108
if (withSource) {
102-
debugger?.lastEvaluatedMetadata?.also { meta ->
103-
it.source = meta.source
104-
it.line = meta.line
105-
if (meta.column != null) it.column = meta.column
106-
}
109+
it.setSourceAndPosition(state.initArgs, debugger?.lastEvaluatedMetadata)
107110
}
108111
})
109112
}
@@ -123,7 +126,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
123126
fun resetEvaluator() {
124127
setEvaluatorState(ItemEvaluator.EvalState.DEFAULT)
125128
if (debugger?.resetEvaluator() == true) {
126-
sendStoppedEvent("step")
129+
sendStoppedEvent(StopReason.STEP)
127130
}
128131
}
129132

@@ -146,6 +149,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
146149
IXplatAbstractions.INSTANCE.sendPacketToPlayer(player, MsgNewSpellPatternAck(it, -1))
147150
}
148151

152+
// TODO: set nonzero exit code if we hit a mishap
149153
if (result.isDone) {
150154
terminate(null)
151155
return view
@@ -158,14 +162,19 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
158162
})
159163
}
160164

161-
sendStoppedEvent(result.reason.value)
165+
sendStoppedEvent(result.reason)
166+
167+
debugger?.getNextIotaToEvaluate()?.also { (iota, index) ->
168+
printDebuggerStatus(iota, index)
169+
}
170+
162171
return view
163172
}
164173

165-
private fun sendStoppedEvent(reason: String) {
174+
private fun sendStoppedEvent(reason: StopReason) {
166175
remoteProxy.stopped(StoppedEventArguments().also {
167176
it.threadId = 0
168-
it.reason = reason
177+
it.reason = reason.value
169178
})
170179
}
171180

@@ -180,7 +189,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
180189
// initialization
181190

182191
override fun initialize(args: InitializeRequestArguments): CompletableFuture<Capabilities> {
183-
state = Initialized(args)
192+
state.initArgs = args
184193
return Capabilities().apply {
185194
supportsConfigurationDoneRequest = true
186195
supportsLoadedSourcesRequest = true
@@ -205,8 +214,11 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
205214
}
206215

207216
override fun attach(args: MutableMap<String, Any>): CompletableFuture<Void> {
208-
val initArgs = state.initArgs ?: return futureOf()
209-
state = NotDebugging(initArgs, LaunchArgs(args))
217+
state.apply {
218+
isConnected = true
219+
launchArgs = LaunchArgs(args)
220+
}
221+
remoteProxy.initialized()
210222
player.displayClientMessage(Component.translatable("text.hexdebug.connected"), true)
211223
return futureOf()
212224
}
@@ -233,7 +245,7 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
233245

234246
override fun configurationDone(args: ConfigurationDoneArguments?): CompletableFuture<Void> {
235247
knownPlayers.add(player.uuid)
236-
debugger?.start()?.also(::handleDebuggerStep)
248+
if (isDebugging) sendStoppedEvent(StopReason.STEP)
237249
return futureOf()
238250
}
239251

@@ -265,34 +277,28 @@ open class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
265277
}
266278

267279
override fun restart(args: RestartArguments?): CompletableFuture<Void> {
268-
val state = state
269-
if (state is ReadyToDebug) {
270-
this.state = NotDebugging(state)
271-
state.restartArgs?.run(::startDebugging)
272-
}
280+
state = NotDebugging(state)
281+
state.restartArgs?.run(::startDebugging)
273282
return futureOf()
274283
}
275284

276285
override fun terminate(args: TerminateArguments?): CompletableFuture<Void> {
277-
val state = state
278-
if (state is ReadyToDebug) {
279-
this.state = NotDebugging(state)
280-
remoteProxy.exited(ExitedEventArguments().also { it.exitCode = 0 })
281-
if (state is Debugging) {
282-
for (source in state.debugger.getSources()) {
283-
remoteProxy.loadedSource(LoadedSourceEventArguments().also {
284-
it.source = source
285-
it.reason = LoadedSourceEventArgumentsReason.REMOVED
286-
})
287-
}
286+
debugger?.let { debugger ->
287+
for (source in debugger.getSources()) {
288+
remoteProxy.loadedSource(LoadedSourceEventArguments().also {
289+
it.source = source
290+
it.reason = LoadedSourceEventArgumentsReason.REMOVED
291+
})
288292
}
289-
remoteProxy.invalidated(InvalidatedEventArguments())
290293
}
294+
remoteProxy.invalidated(InvalidatedEventArguments())
295+
remoteProxy.exited(ExitedEventArguments().also { it.exitCode = 0 })
296+
state = NotDebugging(state)
291297
return futureOf()
292298
}
293299

294300
override fun disconnect(args: DisconnectArguments?): CompletableFuture<Void> {
295-
state = NotConnected
301+
state.isConnected = false
296302
return futureOf()
297303
}
298304

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
11
package gay.`object`.hexdebug.adapter
22

3-
import gay.`object`.hexdebug.debugger.HexDebugger
43
import gay.`object`.hexdebug.debugger.CastArgs
4+
import gay.`object`.hexdebug.debugger.HexDebugger
55
import org.eclipse.lsp4j.debug.InitializeRequestArguments
66

77
sealed interface DebugAdapterState {
8-
val initArgs: InitializeRequestArguments? get() = null
9-
10-
object NotConnected : DebugAdapterState
11-
12-
data class Initialized(override val initArgs: InitializeRequestArguments) : DebugAdapterState
13-
14-
sealed interface ReadyToDebug : DebugAdapterState {
15-
override val initArgs: InitializeRequestArguments
16-
val launchArgs: LaunchArgs
17-
val restartArgs: CastArgs? get() = null
18-
}
8+
var isConnected: Boolean
9+
var initArgs: InitializeRequestArguments
10+
var launchArgs: LaunchArgs
11+
val restartArgs: CastArgs?
1912

2013
data class NotDebugging(
21-
override val initArgs: InitializeRequestArguments,
22-
override val launchArgs: LaunchArgs,
14+
override var isConnected: Boolean = false,
15+
override var initArgs: InitializeRequestArguments = defaultInitArgs(),
16+
override var launchArgs: LaunchArgs = LaunchArgs(),
2317
override val restartArgs: CastArgs? = null,
24-
) : ReadyToDebug {
25-
constructor(state: ReadyToDebug) : this(state.initArgs, state.launchArgs, state.restartArgs)
18+
) : DebugAdapterState {
19+
constructor(state: DebugAdapterState) : this(state.isConnected, state.initArgs, state.launchArgs, state.restartArgs)
2620
}
2721

2822
data class Debugging(
29-
override val initArgs: InitializeRequestArguments,
30-
override val launchArgs: LaunchArgs,
31-
val castArgs: CastArgs,
32-
) : ReadyToDebug {
33-
constructor(state: ReadyToDebug, castArgs: CastArgs) : this(state.initArgs, state.launchArgs, castArgs)
34-
35-
val debugger = HexDebugger(initArgs, launchArgs, castArgs)
36-
37-
override val restartArgs get() = castArgs
23+
override var isConnected: Boolean,
24+
override val restartArgs: CastArgs,
25+
val debugger: HexDebugger,
26+
) : DebugAdapterState {
27+
constructor(state: DebugAdapterState, castArgs: CastArgs) : this(
28+
state.isConnected,
29+
castArgs,
30+
HexDebugger(state.initArgs, state.launchArgs, castArgs),
31+
)
32+
33+
override var initArgs by debugger::initArgs
34+
override var launchArgs by debugger::launchArgs
3835
}
3936
}
37+
38+
fun defaultInitArgs() = InitializeRequestArguments().apply {
39+
linesStartAt1 = true
40+
columnsStartAt1 = true
41+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package gay.`object`.hexdebug.adapter
22

3-
class LaunchArgs(data: Map<String, Any>) {
3+
class LaunchArgs(data: Map<String, Any> = mapOf()) {
44
val stopOnEntry: Boolean by data.withDefault { true }
55
val stopOnExit: Boolean by data.withDefault { false }
66
val skipNonEvalFrames: Boolean by data.withDefault { true }

Common/src/main/kotlin/gay/object/hexdebug/adapter/proxy/DebugProxyClient.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import dev.architectury.event.events.client.ClientPlayerEvent
44
import gay.`object`.hexdebug.HexDebug
55
import gay.`object`.hexdebug.config.HexDebugConfig
66
import gay.`object`.hexdebug.items.ItemDebugger
7-
import gay.`object`.hexdebug.networking.HexDebugNetworking
8-
import gay.`object`.hexdebug.networking.MsgDebugAdapterProxyC2S
7+
import gay.`object`.hexdebug.networking.msg.MsgDebugAdapterProxyC2S
98
import io.ktor.network.selector.*
109
import io.ktor.network.sockets.*
1110
import io.ktor.utils.io.jvm.javaio.*
@@ -140,7 +139,7 @@ class DebugProxyClientProducer(input: InputStream) : StreamMessageProducer(input
140139

141140
// instead of parsing the message here, just forward it to the server
142141
val content = String(buffer, charset(headers.charset))
143-
HexDebugNetworking.sendToServer(MsgDebugAdapterProxyC2S(content))
142+
MsgDebugAdapterProxyC2S(content).sendToServer()
144143
} catch (exception: Exception) {
145144
// UnsupportedEncodingException can be thrown by String constructor
146145
// JsonParseException can be thrown by jsonHandler

Common/src/main/kotlin/gay/object/hexdebug/adapter/proxy/DebugProxyServer.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ package gay.`object`.hexdebug.adapter.proxy
22

33
import gay.`object`.hexdebug.adapter.DebugAdapter
44
import gay.`object`.hexdebug.adapter.IHexDebugLauncher
5-
import gay.`object`.hexdebug.networking.HexDebugNetworking
6-
import gay.`object`.hexdebug.networking.MsgDebugAdapterProxyS2C
5+
import gay.`object`.hexdebug.networking.msg.MsgDebugAdapterProxyS2C
76
import net.minecraft.server.level.ServerPlayer
87
import org.eclipse.lsp4j.debug.services.IDebugProtocolClient
98
import org.eclipse.lsp4j.jsonrpc.*
@@ -106,7 +105,7 @@ class DebugProxyServerConsumer(
106105
override fun consume(message: Message) {
107106
try {
108107
val content = jsonHandler.serialize(message)
109-
HexDebugNetworking.sendToPlayer(player, MsgDebugAdapterProxyS2C(content))
108+
MsgDebugAdapterProxyS2C(content).sendToPlayer(player)
110109
} catch (exception: IOException) {
111110
throw JsonRpcException(exception)
112111
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,17 @@ object HexDebugConfig {
4646

4747
@Tooltip
4848
val smartDebuggerSneakScroll: Boolean = true
49+
50+
@Tooltip
51+
val debuggerDisplayMode: DebuggerDisplayMode = DebuggerDisplayMode.ENABLED
52+
53+
@Tooltip
54+
val showDebugClientLineNumber: Boolean = false
4955
}
5056
}
57+
58+
enum class DebuggerDisplayMode {
59+
DISABLED,
60+
NOT_CONNECTED,
61+
ENABLED,
62+
}

0 commit comments

Comments
 (0)