Compare commits
No commits in common. "a9b191eb725a618603f0ef0eb2b8ae418ec61700" and "20b3fe78ba2e86e8422aae9dd31ac47cc716c0c4" have entirely different histories.
a9b191eb72
...
20b3fe78ba
@ -1,8 +1,11 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity.cable
|
package ru.dbotthepony.mc.otm.block.entity.cable
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntLists
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||||
@ -16,7 +19,6 @@ import ru.dbotthepony.mc.otm.onceServer
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
import kotlin.collections.LinkedHashSet
|
|
||||||
import kotlin.math.ln
|
import kotlin.math.ln
|
||||||
|
|
||||||
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
||||||
@ -67,7 +69,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SegmentPath(private val a: BlockPos, private val b: BlockPos) {
|
class SegmentPath(private val a: BlockPos, private val b: BlockPos) {
|
||||||
val segments = LinkedHashSet<Segment>()
|
val segments = ObjectLinkedOpenHashSet<Segment>()
|
||||||
private var shortCircuit = false
|
private var shortCircuit = false
|
||||||
private var lastTickTransfers = 0
|
private var lastTickTransfers = 0
|
||||||
private var lastTick = 0
|
private var lastTick = 0
|
||||||
@ -132,25 +134,13 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
nodes.add(node)
|
nodes.add(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nodes = LinkedHashSet<EnergyCableBlockEntity.Node>()
|
private val nodes = ObjectLinkedOpenHashSet<EnergyCableBlockEntity.Node>()
|
||||||
private var paths = ReferenceLinkedOpenHashSet<SegmentPath>()
|
private val paths = ReferenceOpenHashSet<SegmentPath>()
|
||||||
|
|
||||||
operator fun contains(node: EnergyCableBlockEntity.Node): Boolean {
|
operator fun contains(node: EnergyCableBlockEntity.Node): Boolean {
|
||||||
return node in nodes
|
return node in nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
fun missingNodes(from: Collection<EnergyCableBlockEntity.Node>): List<EnergyCableBlockEntity.Node> {
|
|
||||||
val missing = ArrayList<EnergyCableBlockEntity.Node>()
|
|
||||||
|
|
||||||
this.nodes.forEach {
|
|
||||||
if (it !in from) {
|
|
||||||
missing.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return missing
|
|
||||||
}
|
|
||||||
|
|
||||||
var throughput = Decimal.ZERO
|
var throughput = Decimal.ZERO
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -294,9 +284,8 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun add(path: SegmentPath) {
|
fun add(path: SegmentPath) {
|
||||||
if (paths.add(path)) {
|
check(paths.add(path)) { "Path $path shouldn't contain $this" }
|
||||||
check(path.segments.add(this)) { "Path set and Segment disagree whenever $this is absent from $path" }
|
check(path.segments.add(this)) { "Path set and Segment disagree whenever $this is absent from $path" }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(path: SegmentPath) {
|
fun remove(path: SegmentPath) {
|
||||||
@ -306,23 +295,23 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
|
|
||||||
// breaks "instant snapshots" of segments atm
|
// breaks "instant snapshots" of segments atm
|
||||||
// shouldn't cause major gameplay issues though
|
// shouldn't cause major gameplay issues though
|
||||||
fun split(nodes: Collection<EnergyCableBlockEntity.Node>): List<Segment> {
|
fun split(): List<Segment> {
|
||||||
for (node in nodes)
|
if (nodes.isEmpty()) {
|
||||||
require(node in this.nodes) { "$node does not belong to $this" }
|
throw IllegalStateException("Empty segment somehow?")
|
||||||
|
} else if (nodes.size == 1) {
|
||||||
if (this.nodes.size == 1) {
|
|
||||||
return listOf(this)
|
return listOf(this)
|
||||||
} else {
|
} else {
|
||||||
|
lastPoweredStatus = 0
|
||||||
|
val list = ArrayList(nodes)
|
||||||
|
val itr = list.iterator()
|
||||||
|
itr.next()
|
||||||
val result = ArrayList<Segment>()
|
val result = ArrayList<Segment>()
|
||||||
result.add(this)
|
result.add(this)
|
||||||
|
|
||||||
for (v in nodes) {
|
for (v in itr) {
|
||||||
v.segment = Segment()
|
v.segment = Segment()
|
||||||
v.segment.throughput = v.energyThroughput
|
|
||||||
v.segment.throughputKnown = true
|
|
||||||
v.segment.transferredLastTick = transferredLastTick
|
v.segment.transferredLastTick = transferredLastTick
|
||||||
v.segment.lastPoweredStatus = lastPoweredStatus
|
v.segment.paths.addAll(paths)
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -402,7 +391,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
|
|
||||||
if (first.node === b) {
|
if (first.node === b) {
|
||||||
// solution found
|
// solution found
|
||||||
val solution = LinkedHashSet<EnergyCableBlockEntity.Node>()
|
val solution = ArrayList<EnergyCableBlockEntity.Node>()
|
||||||
|
|
||||||
var last = first.parent
|
var last = first.parent
|
||||||
solution.add(first.node)
|
solution.add(first.node)
|
||||||
@ -413,23 +402,10 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
}
|
}
|
||||||
|
|
||||||
val touchedSegments = ReferenceArraySet<Segment>()
|
val touchedSegments = ReferenceArraySet<Segment>()
|
||||||
|
solution.forEach { touchedSegments.addAll(it.segment.split()) }
|
||||||
for (it in solution) {
|
|
||||||
if (it.segment in touchedSegments)
|
|
||||||
continue
|
|
||||||
|
|
||||||
val diff = it.segment.missingNodes(solution)
|
|
||||||
|
|
||||||
// segment satisfies new constraints
|
|
||||||
if (diff.isEmpty()) {
|
|
||||||
touchedSegments.add(it.segment)
|
|
||||||
} else {
|
|
||||||
touchedSegments.addAll(it.segment.split(diff))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val path = SegmentPath(a.blockEntity.blockPos, b.blockEntity.blockPos)
|
val path = SegmentPath(a.blockEntity.blockPos, b.blockEntity.blockPos)
|
||||||
solution.forEach { it.segment.add(path) }
|
solution.forEach { it.segment.add(path) }
|
||||||
|
|
||||||
touchedSegments.forEach { it.tryCombine(touchedSegments) }
|
touchedSegments.forEach { it.tryCombine(touchedSegments) }
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
Loading…
Reference in New Issue
Block a user