Add basic sack util
[no changelog]
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
|
||||
|
||||
package moe.nea.firmament.util
|
||||
|
||||
import net.minecraft.text.MutableText
|
||||
import net.minecraft.text.PlainTextContent
|
||||
import net.minecraft.text.Style
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.text.TranslatableTextContent
|
||||
import net.minecraft.util.Formatting
|
||||
@@ -12,106 +9,107 @@ import moe.nea.firmament.Firmament
|
||||
|
||||
|
||||
class TextMatcher(text: Text) {
|
||||
data class State(
|
||||
var iterator: MutableList<Text>,
|
||||
var currentText: Text?,
|
||||
var offset: Int,
|
||||
var textContent: String,
|
||||
)
|
||||
data class State(
|
||||
var iterator: MutableList<Text>,
|
||||
var currentText: Text?,
|
||||
var offset: Int,
|
||||
var textContent: String,
|
||||
)
|
||||
|
||||
var state = State(
|
||||
mutableListOf(text),
|
||||
null,
|
||||
0,
|
||||
""
|
||||
)
|
||||
var state = State(
|
||||
mutableListOf(text),
|
||||
null,
|
||||
0,
|
||||
""
|
||||
)
|
||||
|
||||
fun pollChunk(): Boolean {
|
||||
val firstOrNull = state.iterator.removeFirstOrNull() ?: return false
|
||||
state.offset = 0
|
||||
state.currentText = firstOrNull
|
||||
state.textContent = when (val content = firstOrNull.content) {
|
||||
is PlainTextContent.Literal -> content.string
|
||||
else -> {
|
||||
Firmament.logger.warn("TextContent of type ${content.javaClass} not understood.")
|
||||
return false
|
||||
}
|
||||
}
|
||||
state.iterator.addAll(0, firstOrNull.siblings)
|
||||
return true
|
||||
}
|
||||
fun pollChunk(): Boolean {
|
||||
val firstOrNull = state.iterator.removeFirstOrNull() ?: return false
|
||||
state.offset = 0
|
||||
state.currentText = firstOrNull
|
||||
state.textContent = when (val content = firstOrNull.content) {
|
||||
is PlainTextContent.Literal -> content.string
|
||||
else -> {
|
||||
Firmament.logger.warn("TextContent of type ${content.javaClass} not understood.")
|
||||
return false
|
||||
}
|
||||
}
|
||||
state.iterator.addAll(0, firstOrNull.siblings)
|
||||
return true
|
||||
}
|
||||
|
||||
fun pollChunks(): Boolean {
|
||||
while (state.offset !in state.textContent.indices) {
|
||||
if (!pollChunk()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
fun pollChunks(): Boolean {
|
||||
while (state.offset !in state.textContent.indices) {
|
||||
if (!pollChunk()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun pollChar(): Char? {
|
||||
if (!pollChunks()) return null
|
||||
return state.textContent[state.offset++]
|
||||
}
|
||||
fun pollChar(): Char? {
|
||||
if (!pollChunks()) return null
|
||||
return state.textContent[state.offset++]
|
||||
}
|
||||
|
||||
|
||||
fun expectString(string: String): Boolean {
|
||||
var found = ""
|
||||
while (found.length < string.length) {
|
||||
if (!pollChunks()) return false
|
||||
val takeable = state.textContent.drop(state.offset).take(string.length - found.length)
|
||||
state.offset += takeable.length
|
||||
found += takeable
|
||||
}
|
||||
return found == string
|
||||
}
|
||||
fun expectString(string: String): Boolean {
|
||||
var found = ""
|
||||
while (found.length < string.length) {
|
||||
if (!pollChunks()) return false
|
||||
val takeable = state.textContent.drop(state.offset).take(string.length - found.length)
|
||||
state.offset += takeable.length
|
||||
found += takeable
|
||||
}
|
||||
return found == string
|
||||
}
|
||||
}
|
||||
|
||||
val formattingChars = "kmolnrKMOLNR".toSet()
|
||||
fun CharSequence.removeColorCodes(keepNonColorCodes: Boolean = false): String {
|
||||
var nextParagraph = indexOf('§')
|
||||
if (nextParagraph < 0) return this.toString()
|
||||
val stringBuffer = StringBuilder(this.length)
|
||||
var readIndex = 0
|
||||
while (nextParagraph >= 0) {
|
||||
stringBuffer.append(this, readIndex, nextParagraph)
|
||||
if (keepNonColorCodes && nextParagraph + 1 < length && this[nextParagraph + 1] in formattingChars) {
|
||||
readIndex = nextParagraph
|
||||
nextParagraph = indexOf('§', startIndex = readIndex + 1)
|
||||
} else {
|
||||
readIndex = nextParagraph + 2
|
||||
nextParagraph = indexOf('§', startIndex = readIndex)
|
||||
}
|
||||
if (readIndex > this.length)
|
||||
readIndex = this.length
|
||||
}
|
||||
stringBuffer.append(this, readIndex, this.length)
|
||||
return stringBuffer.toString()
|
||||
var nextParagraph = indexOf('§')
|
||||
if (nextParagraph < 0) return this.toString()
|
||||
val stringBuffer = StringBuilder(this.length)
|
||||
var readIndex = 0
|
||||
while (nextParagraph >= 0) {
|
||||
stringBuffer.append(this, readIndex, nextParagraph)
|
||||
if (keepNonColorCodes && nextParagraph + 1 < length && this[nextParagraph + 1] in formattingChars) {
|
||||
readIndex = nextParagraph
|
||||
nextParagraph = indexOf('§', startIndex = readIndex + 1)
|
||||
} else {
|
||||
readIndex = nextParagraph + 2
|
||||
nextParagraph = indexOf('§', startIndex = readIndex)
|
||||
}
|
||||
if (readIndex > this.length)
|
||||
readIndex = this.length
|
||||
}
|
||||
stringBuffer.append(this, readIndex, this.length)
|
||||
return stringBuffer.toString()
|
||||
}
|
||||
|
||||
val Text.unformattedString: String
|
||||
get() = string.removeColorCodes()
|
||||
get() = string.removeColorCodes()
|
||||
|
||||
fun Text.allSiblings(): List<Text> = listOf(this) + siblings.flatMap { it.allSiblings() }
|
||||
|
||||
fun MutableText.withColor(formatting: Formatting) = this.styled { it.withColor(formatting).withItalic(false) }
|
||||
|
||||
fun Text.transformEachRecursively(function: (Text) -> Text): Text {
|
||||
val c = this.content
|
||||
if (c is TranslatableTextContent) {
|
||||
return Text.translatableWithFallback(c.key, c.fallback, *c.args.map {
|
||||
(if (it is Text) it else Text.literal(it.toString())).transformEachRecursively(function)
|
||||
}.toTypedArray()).also { new ->
|
||||
new.style = this.style
|
||||
new.siblings.clear()
|
||||
this.siblings.forEach { child ->
|
||||
new.siblings.add(child.transformEachRecursively(function))
|
||||
}
|
||||
}
|
||||
}
|
||||
return function(this.copy().also { it.siblings.clear() }).also { tt ->
|
||||
this.siblings.forEach {
|
||||
tt.siblings.add(it.transformEachRecursively(function))
|
||||
}
|
||||
}
|
||||
val c = this.content
|
||||
if (c is TranslatableTextContent) {
|
||||
return Text.translatableWithFallback(c.key, c.fallback, *c.args.map {
|
||||
(if (it is Text) it else Text.literal(it.toString())).transformEachRecursively(function)
|
||||
}.toTypedArray()).also { new ->
|
||||
new.style = this.style
|
||||
new.siblings.clear()
|
||||
this.siblings.forEach { child ->
|
||||
new.siblings.add(child.transformEachRecursively(function))
|
||||
}
|
||||
}
|
||||
}
|
||||
return function(this.copy().also { it.siblings.clear() }).also { tt ->
|
||||
this.siblings.forEach {
|
||||
tt.siblings.add(it.transformEachRecursively(function))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user