Compare commits

...

5 Commits

3 changed files with 66 additions and 7 deletions

View File

@ -413,7 +413,6 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
} }
private var _subCache: ChunkSubscribers? = null private var _subCache: ChunkSubscribers? = null
private val subscription get() = _subCache ?: subscribe()
private var playerListUpdated = false private var playerListUpdated = false
private fun unsubscribe() { private fun unsubscribe() {
@ -430,7 +429,10 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
playerListUpdated = false playerListUpdated = false
} }
private fun subscribe(): ChunkSubscribers { private fun subscribe() {
if (!syncher.hasChildren)
return
val level = level val level = level
check(level is ServerLevel) { "Invalid realm" } check(level is ServerLevel) { "Invalid realm" }
unsubscribe() unsubscribe()
@ -442,7 +444,6 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
subs.subscribe(this) subs.subscribe(this)
_subCache = subs _subCache = subs
playerListUpdated = true playerListUpdated = true
return subs
} }
private class ChunkSubscribers(level: ServerLevel, val chunkPos: Long) { private class ChunkSubscribers(level: ServerLevel, val chunkPos: Long) {

View File

@ -21,6 +21,56 @@ import kotlin.collections.HashSet
import kotlin.collections.LinkedHashSet import kotlin.collections.LinkedHashSet
import kotlin.math.ln import kotlin.math.ln
private class LinkedPriorityQueue<T : Comparable<T>> {
private class Entry<T>(val value: T) {
var next: Entry<T>? = null
}
private var head: Entry<T>? = null
fun isNotEmpty(): Boolean {
return head != null
}
fun add(value: T) {
if (head == null) {
head = Entry(value)
} else if (head!!.value >= value) {
val entry = Entry(value)
entry.next = head
head = entry
} else {
var current = head
var previous = current
while (current != null) {
if (current.value >= value) {
val entry = Entry(value)
entry.next = current
previous!!.next = entry
return
}
previous = current
current = current.next
}
previous!!.next = Entry(value)
}
}
fun remove(): T? {
val head = head
if (head != null) {
this.head = head.next
return head.value
}
return null
}
}
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() { class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
private val livelyNodes = HashSet<EnergyCableBlockEntity.Node>() private val livelyNodes = HashSet<EnergyCableBlockEntity.Node>()
private val livelyNodesList = ArrayList<EnergyCableBlockEntity.Node>() private val livelyNodesList = ArrayList<EnergyCableBlockEntity.Node>()
@ -335,10 +385,13 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
v.segment.transferredLastTick = transferredLastTick v.segment.transferredLastTick = transferredLastTick
v.segment.lastPoweredStatus = lastPoweredStatus v.segment.lastPoweredStatus = lastPoweredStatus
v.segment.paths = paths.clone() v.segment.paths = paths.clone()
paths.forEach { it.segments.add(v.segment) } paths.forEach { it.segments.add(v.segment) }
result.add(v.segment) result.add(v.segment)
} }
paths.forEach { it.nodes.addAll(nodes) }
return result return result
} }
} }
@ -418,14 +471,16 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
return null return null
} }
val openNodes = PriorityQueue<SearchNode>() val openNodes = LinkedPriorityQueue<SearchNode>()
val seenNodes = HashSet<EnergyCableBlockEntity.Node>() val seenNodes = HashSet<EnergyCableBlockEntity.Node>()
openNodes.add(SearchNode(a, b, null, seenTop)) openNodes.add(SearchNode(a, b, null, seenTop))
val existingNodes = HashSet<EnergyCableBlockEntity.Node>()
existing.forEach { existingNodes.addAll(it.nodes) }
while (openNodes.isNotEmpty()) { while (openNodes.isNotEmpty()) {
val first = openNodes.remove() val first = openNodes.remove()!!
openNodes.remove(first)
if (first.node === b) { if (first.node === b) {
// solution found // solution found
@ -463,7 +518,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
} else { } else {
for (neighbour in first.node.neighboursView.values) { for (neighbour in first.node.neighboursView.values) {
if (!seenNodes.add(neighbour) || !neighbour.canTraverse) continue if (!seenNodes.add(neighbour) || !neighbour.canTraverse) continue
val seen = existing.any { neighbour in it } val seen = neighbour in existingNodes
if (seen && neighbour.energyThroughput <= threshold) continue if (seen && neighbour.energyThroughput <= threshold) continue
openNodes.add(SearchNode(neighbour, b, first, seen)) openNodes.add(SearchNode(neighbour, b, first, seen))
} }

View File

@ -66,6 +66,9 @@ class SynchableGroup : Observer, ISynchable, Iterable<ISynchable> {
override val hasRemotes: Boolean override val hasRemotes: Boolean
get() = remotes.isNotEmpty() get() = remotes.isNotEmpty()
val hasChildren: Boolean
get() = slots.any { it != null }
override fun iterator(): Iterator<ISynchable> { override fun iterator(): Iterator<ISynchable> {
return slots.iterator().map { it?.synchable }.filterNotNull() return slots.iterator().map { it?.synchable }.filterNotNull()
} }