task processor, add locations to parser combinator
This commit is contained in:
70
src/main/kotlin/blitz/async/Processor.kt
Normal file
70
src/main/kotlin/blitz/async/Processor.kt
Normal file
@@ -0,0 +1,70 @@
|
||||
package blitz.async
|
||||
|
||||
import blitz.collections.SynchronizedList
|
||||
import blitz.logic.then
|
||||
|
||||
abstract class Processor {
|
||||
protected val tasks = SynchronizedList(mutableListOf<Task>())
|
||||
|
||||
|
||||
fun tick() {
|
||||
for (task in tasks) {
|
||||
if (task.counter >= task.priority) {
|
||||
task.fn()
|
||||
task.counter = 0
|
||||
} else {
|
||||
task.counter ++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun add(task: Task)
|
||||
|
||||
abstract fun remove(task: Task)
|
||||
|
||||
/** priority 0 means every tick; 1 means every second tick; 2 means every third tick, ... */
|
||||
data class Task(
|
||||
internal val priority: Int = 0, // every tick
|
||||
internal val fn: () -> Unit
|
||||
) {
|
||||
internal var counter: Int = 0
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun singleThread(): Processor =
|
||||
SingleThreadProcessor()
|
||||
|
||||
fun manualTick(): Processor =
|
||||
object : Processor() {
|
||||
override fun add(task: Task) {
|
||||
tasks.add(task)
|
||||
}
|
||||
|
||||
override fun remove(task: Task) {
|
||||
tasks.remove(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class SingleThreadProcessor: Processor() {
|
||||
private fun createThread() = Thread { while (true) { tick() } }
|
||||
|
||||
private var thread: Thread? = null
|
||||
|
||||
override fun add(task: Task) {
|
||||
tasks.add(task)
|
||||
if (thread == null) {
|
||||
thread = createThread()
|
||||
thread!!.start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove(task: Task) {
|
||||
tasks.remove(task)
|
||||
tasks.isEmpty().then {
|
||||
runCatching { thread?.interrupt() }
|
||||
thread = null
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +1,10 @@
|
||||
package blitz.parse.comb
|
||||
|
||||
import blitz.str.collectToString
|
||||
import kotlin.math.max
|
||||
|
||||
@JvmInline
|
||||
value class Parsable(
|
||||
val str: String
|
||||
data class Parsable(
|
||||
val str: String,
|
||||
val loc: Int? = null
|
||||
)
|
||||
|
||||
typealias Parser<T> = (Parsable) -> Pair<Parsable, T>?
|
||||
@@ -26,21 +25,24 @@ infix fun <T> Parser<T>.or(other: Parser<T>): Parser<T> = {
|
||||
}
|
||||
|
||||
fun Parsable.spaces(): Parsable {
|
||||
return Parsable(str.trimStart(' '))
|
||||
val new = str.trimStart(' ')
|
||||
return Parsable(new, loc?.let { it + str.length - new.length })
|
||||
}
|
||||
|
||||
fun Parsable.whitespaces(): Parsable {
|
||||
return Parsable(str.trimStart())
|
||||
val new = str.trimStart()
|
||||
return Parsable(new, loc?.let { it + str.length - new.length })
|
||||
}
|
||||
|
||||
fun Parsable.require(what: String): Parsable? {
|
||||
if (str.startsWith(what))
|
||||
return Parsable(str.substring(what.length))
|
||||
return Parsable(str.substring(what.length), loc?.let { it + what.length })
|
||||
return null
|
||||
}
|
||||
|
||||
fun <T> Parsable.untilRequire(c: String, map: (String) -> T?): Pair<Parsable, T>? {
|
||||
return map(str.substringBefore(c))?.let { Parsable(str.substringAfter(c)) to it }
|
||||
val before = str.substringBefore(c)
|
||||
return map(before)?.let { Parsable(str.substringAfter(c), loc?.let { it + before.length }) to it }
|
||||
}
|
||||
|
||||
fun <T> Parsable.asLongAs(vararg li: Char, map: (String) -> T?): Pair<Parsable, T>? {
|
||||
@@ -52,7 +54,7 @@ fun <T> Parsable.asLongAs(vararg li: Char, map: (String) -> T?): Pair<Parsable,
|
||||
break
|
||||
}
|
||||
val out = str.substring(o.size)
|
||||
return map(o.iterator().collectToString())?.let { Parsable(out) to it }
|
||||
return map(o.iterator().collectToString())?.let { Parsable(out, loc?.plus(o.size)) to it }
|
||||
}
|
||||
|
||||
fun <T> Parsable.map(parser: Parser<T>): Pair<Parsable, T>? =
|
||||
@@ -89,17 +91,19 @@ fun <T> Pair<Parsable, T>.require(what: String): Pair<Parsable, T>? =
|
||||
fun <T> Parsable.array(sep: String, map: (Parsable) -> Pair<Parsable, T>?): Pair<Parsable, List<T>> {
|
||||
val out = mutableListOf<T>()
|
||||
|
||||
var loc = loc
|
||||
var curr = str
|
||||
fun step() =
|
||||
map(Parsable(curr))?.also {
|
||||
map(Parsable(curr, loc))?.also {
|
||||
curr = it.first.str
|
||||
loc = it.first.loc
|
||||
}
|
||||
|
||||
while (true) {
|
||||
val r = step() ?: break
|
||||
out.add(r.second)
|
||||
curr = (Parsable(curr).require(sep) ?: break).str
|
||||
curr = (Parsable(curr, loc).require(sep) ?: break).str
|
||||
}
|
||||
|
||||
return Parsable(curr) to out
|
||||
return Parsable(curr, loc) to out
|
||||
}
|
Reference in New Issue
Block a user