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
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 {
fun wrap(ticker: () -> Boolean): IConditionalTickable {
return object : IConditionalTickable {
override var canTick: Boolean = true
private set
fun wrap(ticker: () -> Boolean): IConditionalTickable = IConditionalTickable { ticker.invoke() }
fun wrap(ticker: BooleanSupplier): IConditionalTickable = IConditionalTickable { ticker.asBoolean }
override fun tick() {
canTick = !ticker.invoke()
}
fun wrap(condition: () -> Boolean, ticker: () -> Unit): IConditionalTickable {
return IConditionalTickable {
ticker.invoke()
condition.invoke()
}
}
fun wrap(condition: () -> Boolean, ticker: () -> Unit): IConditionalTickable {
return object : IConditionalTickable {
override val canTick: Boolean get() = condition.invoke()
override fun tick() {
ticker.invoke()
}
fun wrap(condition: BooleanSupplier, ticker: () -> Unit): IConditionalTickable {
return IConditionalTickable {
ticker.invoke()
condition.asBoolean
}
}
}

View File

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

View File

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

View File

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

View File

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