Skip to content

Commit

Permalink
Replace the debug method with debug library to allow drawing more things
Browse files Browse the repository at this point in the history
  • Loading branch information
dwursteisen committed Dec 13, 2023
1 parent 96862e5 commit 0e0551d
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ class GameEngine(

private var numberOfResources: Int = 0

private val debugMessages = mutableListOf<DebugMessage>()
private var debugEnabled: Boolean = true
private val debugActions = mutableListOf<DebugAction>()

private lateinit var scripts: Array<GameScript?>
private lateinit var spriteSheets: Array<SpriteSheet?>
Expand Down Expand Up @@ -338,23 +339,49 @@ class GameEngine(
platform.screenshot()
}

debugMessages.forEachIndexed { index, debugMessage ->
val (msg, color) = debugMessage
engineGameScript?.invoke(
"printDebug",
valueOf(index),
valueOf(msg),
valueOf(color),
)
var msgIndex = 0
if (!debugEnabled) {
debugActions.clear()
}
debugMessages.clear()
debugActions.forEach { debugAction ->
when (debugAction) {
is DebugMessage -> {
val (msg, color) = debugAction
engineGameScript?.invoke(
"printDebug",
valueOf(msgIndex++),
valueOf(msg),
valueOf(color),
)
}

is DebugRect -> {
val (x, y, width, height, color) = debugAction
engineGameScript?.invoke(
"shape.rect",
valueOf(x),
valueOf(y),
valueOf(width),
valueOf(height),
valueOf(color),
)
}
is DebugEnabled -> Unit // NOP
}
}
debugActions.clear()
inputManager.reset()
}
}
}

override fun debug(str: DebugMessage) {
debugMessages.add(str)
override fun debug(action: DebugAction) {
when (action) {
is DebugEnabled -> {
debugEnabled = action.enabled
}
else -> debugActions.add(action)
}
}

private suspend fun GameEngine.popupError(ex: LuaError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import com.github.minigdx.tiny.resources.GameScript
import com.github.minigdx.tiny.resources.Sound
import com.github.minigdx.tiny.resources.SpriteSheet

data class DebugMessage(val mesage: String, val color: String)
sealed interface DebugAction
data class DebugMessage(val mesage: String, val color: String) : DebugAction
data class DebugRect(val x: Int, val y: Int, val width: Int, val height: Int, val color: String, val filed: Boolean = false) : DebugAction

data class DebugEnabled(val enabled: Boolean) : DebugAction

/**
* Descriptor to access the game resource
Expand Down Expand Up @@ -43,8 +47,8 @@ interface GameResourceAccess {
fun script(name: String): GameScript?

/**
* Print a message over the current screen,
* Perform an action (draw message, rect, ...) over the current screen,
* after the game rendered.
*/
fun debug(str: DebugMessage) = Unit
fun debug(action: DebugAction) = Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.github.minigdx.tiny.lua

import com.github.mingdx.tiny.doc.TinyArg
import com.github.mingdx.tiny.doc.TinyArgs
import com.github.mingdx.tiny.doc.TinyCall
import com.github.mingdx.tiny.doc.TinyFunction
import com.github.mingdx.tiny.doc.TinyLib
import com.github.minigdx.tiny.engine.DebugEnabled
import com.github.minigdx.tiny.engine.DebugMessage
import com.github.minigdx.tiny.engine.DebugRect
import com.github.minigdx.tiny.engine.GameResourceAccess
import org.luaj.vm2.LuaTable
import org.luaj.vm2.LuaValue
import org.luaj.vm2.Varargs
import org.luaj.vm2.lib.LibFunction
import org.luaj.vm2.lib.OneArgFunction
import org.luaj.vm2.lib.TwoArgFunction

private class DebugShape {

fun rectArgs(args: Varargs): List<LuaValue>? {
when (args.narg()) {
// rect including color
in 1..1 -> {
val table = args.arg1().opttable(null) ?: return null
return listOf(
table["x"],
table["y"],
table["width"],
table["height"],
table["color"],
)
}
// rect with color
in 2..2 -> {
val table = args.arg1().opttable(null) ?: return null
return listOf(
table["x"],
table["y"],
table["width"],
table["height"],
args.arg(2),
)
}
// not supported
in 3..3 -> {
return null
}
// every args
else -> {
val x = args.arg(1)
val y = args.arg(2)
val width = args.arg(3)
val height = args.arg(4)
val color = args.arg(5)
return listOf(x, y, width, height, color)
}
}
}
}

@TinyLib("debug", "Helpers to debug your game by drawing or printing information on screen.")
class DebugLib(private val resourceAccess: GameResourceAccess) : TwoArgFunction() {

private val shape = DebugShape()

override fun call(arg1: LuaValue, arg2: LuaValue): LuaValue {
val tiny = LuaTable()
tiny["enabled"] = enabled()
tiny["log"] = log()
tiny["rect"] = rect()

arg2["debug"] = tiny
arg2["package"]["loaded"]["debug"] = tiny

return tiny
}

@TinyFunction("Enable or disable debug feature.")
internal inner class enabled : OneArgFunction() {
@TinyCall("Enable or disable debug by passing true to enable, false to disable.")
override fun call(@TinyArg("enabled") arg: LuaValue): LuaValue {
val enabled = arg.optboolean(true)
resourceAccess.debug(DebugEnabled(enabled))
return NIL
}
}

@TinyFunction("Log a message on the screen.")
internal inner class log : TwoArgFunction() {

@TinyCall("Log a message on the screen.")
override fun call(@TinyArg("str") arg1: LuaValue, @TinyArg("color") arg2: LuaValue): LuaValue {
val message = arg1.optjstring("")!!
val color = arg2.optjstring("#32CD32")!!
resourceAccess.debug(DebugMessage(message, color))
return NIL
}

@TinyCall("Log a message on the screen.")
override fun call(@TinyArg("str") arg: LuaValue): LuaValue = super.call(arg)
}

@TinyFunction("Draw a rectangle on the screen")
internal inner class rect : LibFunction() {

@TinyCall("Draw a debug rectangle.")
override fun invoke(@TinyArgs(["x", "y", "width", "height", "color"]) args: Varargs): Varargs {
val (x, y, width, height, color) = shape.rectArgs(args) ?: return NIL
resourceAccess.debug(
DebugRect(
x = x.checkint(),
y = y.checkint(),
width = width.checkint(),
height = height.checkint(),
color = color.optjstring("#32CD32")!!,
),
)
return NIL
}

@TinyCall("Draw a debug rectangle.")
override fun call(@TinyArg("rect", "A rectangle {x, y, width, height, color}") a: LuaValue): LuaValue {
return super.call(a)
}

@TinyCall("Draw a debug rectangle using a rectangle and a color.")
override fun call(
@TinyArg("rect", "A rectangle {x, y, width, height}") a: LuaValue,
@TinyArg("color") b: LuaValue,
): LuaValue = super.call(a, b)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.github.mingdx.tiny.doc.TinyArgs
import com.github.mingdx.tiny.doc.TinyCall
import com.github.mingdx.tiny.doc.TinyFunction
import com.github.mingdx.tiny.doc.TinyLib
import com.github.minigdx.tiny.engine.DebugMessage
import com.github.minigdx.tiny.engine.GameOptions
import com.github.minigdx.tiny.engine.GameResourceAccess
import org.luaj.vm2.LuaTable
Expand All @@ -26,7 +25,6 @@ class StdLib(
arg2["all"] = all()
arg2["rpairs"] = rpairs()
arg2["print"] = print()
arg2["debug"] = debug()
arg2["new"] = new()
return tiny
}
Expand Down Expand Up @@ -119,20 +117,6 @@ class StdLib(
}
}

@TinyFunction("Print in the console a value to help debugging")
internal inner class debug : TwoArgFunction() {

override fun call(arg1: LuaValue, arg2: LuaValue): LuaValue {
val message = arg1.optjstring("")!!
val color = arg2.optjstring("#32CD32")!!
resourceAccess.debug(DebugMessage(message, color))
return NIL
}

@TinyCall("Print in the console a value")
override fun call(arg: LuaValue): LuaValue = super.call(arg)
}

@TinyFunction("Print on the screen a string.", example = STD_PRINT_EXAMPLE)
internal inner class print : LibFunction() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.minigdx.tiny.engine.GameOptions
import com.github.minigdx.tiny.engine.GameResourceAccess
import com.github.minigdx.tiny.input.InputHandler
import com.github.minigdx.tiny.lua.CtrlLib
import com.github.minigdx.tiny.lua.DebugLib
import com.github.minigdx.tiny.lua.GfxLib
import com.github.minigdx.tiny.lua.JuiceLib
import com.github.minigdx.tiny.lua.KeysLib
Expand Down Expand Up @@ -79,6 +80,7 @@ class GameScript(
load(CtrlLib(inputHandler, sprLib))
load(SfxLib(this@GameScript.resourceAccess, playSound = !forValidation))
load(ShapeLib(this@GameScript.resourceAccess))
load(DebugLib(this@GameScript.resourceAccess))
load(KeysLib())
load(MathLib())
load(tinyLib)
Expand Down Expand Up @@ -124,8 +126,17 @@ class GameScript(
}

internal suspend fun invoke(name: String, vararg args: LuaValue) {
val path = name.split(".")
val head = path.first()
val tail = path.drop(1)

var function = globals?.get(head)
tail.forEach {
function = function?.get(it)
}

@Suppress("UNCHECKED_CAST")
globals?.get(name)?.nullIfNil()?.invokeSuspend(args as Array<LuaValue>)
function?.nullIfNil()?.invokeSuspend(args as Array<LuaValue>)
}

suspend fun getState(): State? {
Expand Down

0 comments on commit 0e0551d

Please sign in to comment.