Misc fixes regarding cable network node removals

This commit is contained in:
DBotThePony 2025-02-11 15:55:30 +07:00
parent fcc8fe157e
commit f9bd671e88
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
import ru.dbotthepony.mc.otm.UNIVERSE_TICKS import ru.dbotthepony.mc.otm.UNIVERSE_TICKS
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.config.CablesConfig import ru.dbotthepony.mc.otm.config.CablesConfig
import ru.dbotthepony.mc.otm.core.addAll
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.reduce import ru.dbotthepony.mc.otm.core.collect.reduce
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
@ -186,7 +187,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
nodes.add(node) nodes.add(node)
} }
private val nodes = LinkedHashSet<EnergyCableBlockEntity.Node>() val nodes = LinkedHashSet<EnergyCableBlockEntity.Node>()
var paths = ReferenceLinkedOpenHashSet<SegmentPath>() var paths = ReferenceLinkedOpenHashSet<SegmentPath>()
operator fun contains(node: EnergyCableBlockEntity.Node): Boolean { operator fun contains(node: EnergyCableBlockEntity.Node): Boolean {
@ -244,7 +245,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
val newState = transferredLastTick.isPositive val newState = transferredLastTick.isPositive
val numState = if (newState) 1 else -1 val numState = if (newState) 1 else -1
if (numState != lastPoweredStatus) { if (numState != lastPoweredStatus || true) {
lastPoweredStatus = numState lastPoweredStatus = numState
nodes.forEach { if (it.segment === this) it.updatePoweredState(newState) } nodes.forEach { if (it.segment === this) it.updatePoweredState(newState) }
} }
@ -257,7 +258,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
private fun blockstateUpdateStep() { private fun blockstateUpdateStep() {
val new = updateBlockstates() val new = updateBlockstates()
val changed = hasBlockstateTimer != new val changed = hasBlockstateTimer != new
hasBlockstateTimer = updateBlockstates() hasBlockstateTimer = new
lastPoweredSwitchFrequency = (lastPoweredSwitchFrequency shl 1) or (if (changed) 1 else 0) lastPoweredSwitchFrequency = (lastPoweredSwitchFrequency shl 1) or (if (changed) 1 else 0)
if (hasBlockstateTimer && SERVER_IS_LIVE) { if (hasBlockstateTimer && SERVER_IS_LIVE) {
@ -383,6 +384,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
v.segment = Segment() v.segment = Segment()
v.segment.throughput = v.energyThroughput v.segment.throughput = v.energyThroughput
v.segment.throughputKnown = true v.segment.throughputKnown = true
v.segment.lastTick = lastTick
v.segment.transferredLastTick = transferredLastTick v.segment.transferredLastTick = transferredLastTick
v.segment.paths = paths.clone() v.segment.paths = paths.clone()
v.updatePoweredState(false) v.updatePoweredState(false)
@ -392,6 +394,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
result.add(v.segment) result.add(v.segment)
} }
lastPoweredStatus = 0
paths.forEach { it.nodes.addAll(nodes) } paths.forEach { it.nodes.addAll(nodes) }
return result return result
} }
@ -405,6 +408,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
val segment = Segment() val segment = Segment()
v._segment = segment v._segment = segment
segment.nodes.add(v) segment.nodes.add(v)
segment.lastTick = lastTick
segment.throughput = v.energyThroughput segment.throughput = v.energyThroughput
segment.throughputKnown = true segment.throughputKnown = true
segment.transferredLastTick = transferredLastTick segment.transferredLastTick = transferredLastTick
@ -428,7 +432,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
} }
private fun tryCombineWith(segment: Segment): Boolean { private fun tryCombineWith(segment: Segment): Boolean {
if (segment === this || segment.nodes.isEmpty()) return false if (segment === this || segment.nodes.isEmpty() || segment.paths.isEmpty()) return false
// if nodes have same set of paths then it is safe to combine this with target segment // if nodes have same set of paths then it is safe to combine this with target segment
if (segment.paths == paths) { if (segment.paths == paths) {
@ -456,7 +460,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
} }
fun tryCombine(with: Collection<Segment>) { fun tryCombine(with: Collection<Segment>) {
if (nodes.isEmpty()) return if (nodes.isEmpty() || paths.isEmpty()) return
for (segment in with) { for (segment in with) {
if (tryCombineWith(segment)) return if (tryCombineWith(segment)) return
@ -581,12 +585,23 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
check(livelyNodesList.remove(node)) check(livelyNodesList.remove(node))
} }
node.segment.paths.forEach { val touchedSegments = HashSet<Segment>()
node.segment.paths.toTypedArray().forEach {
pathCache.remove(it.a to it.b) pathCache.remove(it.a to it.b)
it.segments.forEach { s ->
touchedSegments.add(s)
s.paths.remove(it)
// this doesn't cover 100% of cases where previously split path segments
// due to "this" path get recombined, but it should be good enough
s.paths.forEach { touchedSegments.addAll(it.segments) }
}
} }
node.segment.paths = ReferenceLinkedOpenHashSet() touchedSegments.addAll(node.segment.split())
node.segment.split() touchedSegments.forEach { it.tryCombine(touchedSegments) }
} }
override fun onNodeAdded(node: EnergyCableBlockEntity.Node) { override fun onNodeAdded(node: EnergyCableBlockEntity.Node) {