package army.warfare.holo.util.misc
import army.warfare.holo.events.UpdateEvent
import com.darkmagician6.eventapi.EventManager
import com.darkmagician6.eventapi.EventTarget
import kotlinx.coroutines.*
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class SequenceList {
private val sequences = mutableListOf<Sequence>()
fun add(sequence: Sequence) {
sequences.add(sequence)
}
fun register() {
EventManager.register(this)
}
fun unregister() {
EventManager.unregister(this)
}
@EventTarget
fun updateSequences(event: UpdateEvent.Pre) {
for (seq in sequences) {
val angle = seq.tick() ?: continue
if (angle.first != null) {
event.yaw = angle.first!!
}
if (angle.second != null) {
event.pitch = angle.second!!
}
}
}
}
class Sequence(val handler: suspend Sequence.() -> Unit) {
private var continuation: Continuation<Unit>? = null
private var remainingTicks: Int = 0
private var coroutine: Job = buildCoroutine()
private var rotationYaw: Float? = null
private var rotationPitch: Float? = null
private fun buildCoroutine(): Job {
return GlobalScope.launch(Dispatchers.Unconfined) {
sync()
while (isActive) {
handler()
sync()
}
}
}
fun reset() {
remainingTicks = 0
continuation = null
coroutine = buildCoroutine()
}
fun tick(): Pair<Float?, Float?>? {
if (remainingTicks > 0) {
remainingTicks--
} else {
if (coroutine.isActive) {
continuation?.resume(Unit)
if (rotationYaw != null || rotationPitch != null) {
val angle = Pair(rotationYaw, rotationPitch)
rotationYaw = null
rotationPitch = null
return angle
}
}
}
return null
}
suspend fun wait(ticks: Int) {
remainingTicks = ticks
suspendCoroutine<Unit> { continuation = it }
}
fun rotate(yaw: Float?, pitch: Float?) {
rotationYaw = yaw
rotationPitch = pitch
}
suspend fun sync() {
wait(0)
}
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎