package net.torvald.terrarum.modulebasegame.ui import net.torvald.terrarum.AppLoader import java.util.* object UITitleRemoConYaml { // YAML indent with a space, separate label and class with " : " (\x20\x3A\x20) val menus = """ - MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UITitleCharactersList - CONTEXT_CHARACTER_NEW - CONTEXT_CHARACTER_DELETE - MENU_LABEL_RETURN - MENU_MODE_MULTIPLAYER - MENU_LABEL_RETURN - MENU_OPTIONS - MENU_OPTIONS_GRAPHICS - MENU_OPTIONS_CONTROLS - MENU_OPTIONS_SOUND - MENU_LABEL_RETURN - MENU_MODULES : net.torvald.terrarum.modulebasegame.ui.UITitleModules - MENU_LABEL_RETURN - MENU_LABEL_LANGUAGE : net.torvald.terrarum.modulebasegame.ui.UITitleLanguage - MENU_LABEL_RETURN - MENU_LABEL_CREDITS : net.torvald.terrarum.modulebasegame.ui.UITitleCredits - MENU_LABEL_CREDITS : net.torvald.terrarum.modulebasegame.ui.UITitleCredits - MENU_CREDIT_GPL_DNT : net.torvald.terrarum.modulebasegame.ui.UITitleGPL3 - MENU_LABEL_RETURN - MENU_LABEL_QUIT """.trimIndent() val debugTools = """ - Development Tools $ - Building Maker - Start New Random Game - MENU_LABEL_RETURN """.trimIndent() operator fun invoke() = if (AppLoader.IS_DEVELOPMENT_BUILD) parseYamlList(menus + "\n" + debugTools) else parseYamlList(menus) fun parseYamlList(yaml: String): QNDTreeNode { var currentIndentLevel = -1 val root = QNDTreeNode() var currentNode = root val nodesStack = Stack>() nodesStack.push(currentNode) yaml.split('\n') .forEach { val indentLevel = it.countSpaces() val it = it.trimIndent() if (it.startsWith("- ")) { val nodeName = it.drop(2) if (indentLevel == currentIndentLevel) { val sibling = QNDTreeNode(nodeName, currentNode.parent) currentNode.parent!!.children.add(sibling) currentNode = sibling } else if (indentLevel > currentIndentLevel) { val childNode = QNDTreeNode(nodeName, currentNode) currentNode.children.add(childNode) nodesStack.push(currentNode) currentNode = childNode currentIndentLevel = indentLevel } else { repeat(currentIndentLevel - indentLevel) { currentNode = nodesStack.pop() } currentIndentLevel = indentLevel val sibling = QNDTreeNode(nodeName, currentNode.parent) currentNode.parent!!.children.add(sibling) currentNode = sibling } } } // test traverse resulting tree /*root.traversePreorder { node, depth -> repeat(depth + 1) { print("-") } println("${node.data} -> ${node.parent}") }*/ return root } private fun String.countSpaces(): Int { var c = 0 while (c <= this.length) { if (this[c] == ' ') c++ else break } return c } } class QNDTreeNode(var data: T? = null, var parent: QNDTreeNode? = null) { var children = ArrayList>() private fun traverse1(node: QNDTreeNode, action: (QNDTreeNode, Int) -> Unit, depth: Int = 0) { //if (node == null) return action(node, depth) node.children.forEach { traverse1(it, action, depth + 1) } } private fun traverse2(node: QNDTreeNode, action: (QNDTreeNode, Int) -> Unit, depth: Int = 0) { //if (node == null) return node.children.forEach { traverse2(it, action, depth + 1) } action(node, depth) } fun traversePreorder(action: (QNDTreeNode, Int) -> Unit) { this.traverse1(this, action) } fun traversePostorder(action: (QNDTreeNode, Int) -> Unit) { this.traverse2(this, action) } }