Reimagine IConditionalTickable

This commit is contained in:
DBotThePony 2023-03-18 08:32:28 +07:00
parent 6b3e80b629
commit fdae27844a
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 38 additions and 59 deletions

View File

@ -1,35 +1,34 @@
package ru.dbotthepony.mc.otm.core.util package ru.dbotthepony.mc.otm.core.util
import java.util.function.BooleanSupplier
/** /**
* Represents tick callback with condition, once * Represents something that can tick without any additional callback,
* with sign whenever can it tick more
*/ */
interface IConditionalTickable : ITickable { fun interface IConditionalTickable {
/** /**
* Once this returns false, it should stay false. * Function to be called by tick executors
* *
* If it suddenly turns true after being false, result is undefined. * Once this returns false, ticker is considered finished, and should be removed from ticking list
*/ */
val canTick: Boolean fun tick(): Boolean
companion object { companion object {
fun wrap(ticker: () -> Boolean): IConditionalTickable { fun wrap(ticker: () -> Boolean): IConditionalTickable = IConditionalTickable { ticker.invoke() }
return object : IConditionalTickable { fun wrap(ticker: BooleanSupplier): IConditionalTickable = IConditionalTickable { ticker.asBoolean }
override var canTick: Boolean = true
private set
override fun tick() { fun wrap(condition: () -> Boolean, ticker: () -> Unit): IConditionalTickable {
canTick = !ticker.invoke() return IConditionalTickable {
} ticker.invoke()
condition.invoke()
} }
} }
fun wrap(condition: () -> Boolean, ticker: () -> Unit): IConditionalTickable { fun wrap(condition: BooleanSupplier, ticker: () -> Unit): IConditionalTickable {
return object : IConditionalTickable { return IConditionalTickable {
override val canTick: Boolean get() = condition.invoke() ticker.invoke()
condition.asBoolean
override fun tick() {
ticker.invoke()
}
} }
} }
} }

View File

@ -1,8 +1,11 @@
package ru.dbotthepony.mc.otm.core.util package ru.dbotthepony.mc.otm.core.util
/** /**
* Represents tick callback * Represents something that can tick without any additional context
*/ */
fun interface ITickable { fun interface ITickable {
/**
* Function to be called by tick executors
*/
fun tick() fun tick()
} }

View File

@ -163,10 +163,9 @@ class TickList : ITickable {
val iterator = conditional.iterator() val iterator = conditional.iterator()
for (ticker in iterator) { for (ticker in iterator) {
if (!ticker.canTick) { if (!ticker.tick()) {
iterator.remove() iterator.remove()
} else { } else {
ticker.tick()
nothingToDo = false nothingToDo = false
} }
} }

View File

@ -27,19 +27,16 @@ abstract class Abstract6Graph<T> : IConditionalTickable {
abstract fun onNodeRemoved(node: Graph6Node<T>) abstract fun onNodeRemoved(node: Graph6Node<T>)
abstract fun onNodeAdded(node: Graph6Node<T>) abstract fun onNodeAdded(node: Graph6Node<T>)
override val canTick: Boolean override fun tick(): Boolean {
get() = nodes.size > 0
override fun tick() {
for (i in tickable.size - 1 downTo 0) { for (i in tickable.size - 1 downTo 0) {
val node = tickable[i] val node = tickable[i]
if (node.canTick) { if (!node.tick()) {
node.tick()
} else {
tickable.removeAt(i) tickable.removeAt(i)
} }
} }
return nodes.size > 0
} }
fun removeNode(node: Graph6Node<T>) { fun removeNode(node: Graph6Node<T>) {
@ -48,10 +45,7 @@ abstract class Abstract6Graph<T> : IConditionalTickable {
node.graph = null node.graph = null
onNodeRemoved(node) onNodeRemoved(node)
tickable.remove(node)
if (node.canTick) {
tickable.remove(node)
}
} }
fun addNode(node: Graph6Node<T>) { fun addNode(node: Graph6Node<T>) {
@ -61,10 +55,7 @@ abstract class Abstract6Graph<T> : IConditionalTickable {
nodes.add(node) nodes.add(node)
node.graph = this node.graph = this
onNodeAdded(node) onNodeAdded(node)
tickable.add(node)
if (node.canTick) {
tickable.add(node)
}
} }
fun merge(other: Abstract6Graph<T>): Abstract6Graph<T> { fun merge(other: Abstract6Graph<T>): Abstract6Graph<T> {
@ -92,16 +83,9 @@ abstract class Abstract6Graph<T> : IConditionalTickable {
nodeGetter: (BlockEntity) -> Graph6Node<T>?, nodeGetter: (BlockEntity) -> Graph6Node<T>?,
factory: () -> Abstract6Graph<T> factory: () -> Abstract6Graph<T>
) { ) {
level.addTicker(object : IConditionalTickable { level.addTicker {
override fun tick() { !discover(level, blockPos, node, nodeGetter, factory) && node.valid
discovered = discover(level, blockPos, node, nodeGetter, factory) }
}
private var discovered = false
override val canTick: Boolean
get() = !discovered && node.valid
})
} }
@JvmStatic @JvmStatic

View File

@ -185,20 +185,14 @@ class Graph6Node<T>(@JvmField val value: T, graph: Abstract6Graph<T>? = null) :
} }
} }
override val canTick: Boolean override fun tick(): Boolean {
get() { if (value is IConditionalTickable) {
return if (value is IConditionalTickable) { return value.tick()
value.canTick } else if (value is ITickable) {
} else {
value is ITickable
}
}
override fun tick() {
if (value is ITickable) {
value.tick() value.tick()
return true
} else { } else {
throw ClassCastException("$value is not tickable") return false
} }
} }