diff --git a/src/main/kotlin/org/neoflock/neocomputers/network/DeviceNode.kt b/src/main/kotlin/org/neoflock/neocomputers/network/DeviceNode.kt index 1c624e3..71f5737 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/network/DeviceNode.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/network/DeviceNode.kt @@ -40,6 +40,10 @@ open class DeviceNode(_address: UUID? = null) { return maximum } + val boundNetworks = HashSet() + // meaningless except visibility is NETWORK, where there can only be one + fun getPrimaryNetwork() = boundNetworks.firstOrNull() + fun getChargerNodes(): Set = getReachable().filter { it.powerRole != PowerRole.CONSUMER }.toSet() fun totalEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energy } fun maxEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energyCapacity } @@ -170,9 +174,6 @@ open class DeviceNode(_address: UUID? = null) { if(reachability == Visibility.SOME) { return getPreferredFew() } - if(reachability == Visibility.DIRECT) { - return connections.minus(this) - } if(reachability == Visibility.NETWORK) { // absolute cinema val working = HashSet() @@ -185,8 +186,6 @@ open class DeviceNode(_address: UUID? = null) { working.add(subnode) if(subnode.reachability == Visibility.NETWORK) { pending.addAll(subnode.connections) - } else if(subnode.reachability == Visibility.DIRECT) { - working.addAll(subnode.connections) } else if(subnode.reachability == Visibility.SOME) { pending.addAll(subnode.getPreferredFew()) } diff --git a/src/main/kotlin/org/neoflock/neocomputers/network/LocalNetwork.kt b/src/main/kotlin/org/neoflock/neocomputers/network/LocalNetwork.kt new file mode 100644 index 0000000..7fe5aba --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/network/LocalNetwork.kt @@ -0,0 +1,70 @@ +package org.neoflock.neocomputers.network + +class LocalNetwork(val sourceOfTruth: DeviceNode) { + val devices = HashSet() + + fun getReachableByTruth() = sourceOfTruth.computeReachable() + + fun performMerge(other: LocalNetwork) { + for(dev in other.devices) { + if(other in dev.boundNetworks) { + dev.boundNetworks.remove(other) + dev.boundNetworks.add(this) + } + devices.add(dev) + } + other.devices.clear() + } + + fun addToNetwork(dev: DeviceNode) { + if(dev in devices) return + if(dev.reachability == Networking.Visibility.NETWORK) { + val primNet = dev.getPrimaryNetwork() + if(primNet != null) { + // Merge the networks! + // merge smallest into largest for perf + if(primNet.devices.size > devices.size) { + primNet.performMerge(this) + } else { + performMerge(primNet) + } + return + } + } + + devices.add(dev) + dev.boundNetworks.add(this) + + when(dev.reachability) { + Networking.Visibility.NONE -> return + Networking.Visibility.SOME -> { + dev.getPreferredFew().forEach { addToNetwork(it) } + } + Networking.Visibility.NETWORK -> { + dev.connections.forEach { addToNetwork(it) } + } + } + } + + fun checkIfStillConnected(dev: DeviceNode) { + if(dev !in devices) return + if(dev in getReachableByTruth()) return + removeFromNetwork(dev) + } + + fun removeFromNetwork(dev: DeviceNode) { + // TODO: this is wrong, rewrite it. We need it to make a sub-network. + if(dev == sourceOfTruth) { + throw UnsupportedOperationException("removing the source of truth is not supported") + } + if(dev !in devices) return + devices.remove(dev) + dev.boundNetworks.remove(this) + + when(dev.reachability) { + Networking.Visibility.NONE -> {} + Networking.Visibility.SOME -> dev.getPreferredFew().forEach { removeFromNetwork(it) } + Networking.Visibility.NETWORK -> dev.connections.forEach { removeFromNetwork(it) } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/network/Networking.kt b/src/main/kotlin/org/neoflock/neocomputers/network/Networking.kt index 29e9649..e50c25f 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/network/Networking.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/network/Networking.kt @@ -30,8 +30,6 @@ object Networking { NONE, // some, as determined by getPreferredFew() SOME, - // can only see its direct connections - DIRECT, // Can see everything network-wide NETWORK, }