networking bullshit
This commit is contained in:
@@ -11,6 +11,15 @@ plugins {
|
|||||||
val minecraft = stonecutter.current.version
|
val minecraft = stonecutter.current.version
|
||||||
val loader = loom.platform.get().name.lowercase()
|
val loader = loom.platform.get().name.lowercase()
|
||||||
|
|
||||||
|
fun minecraftVersionToNum(ver: String): Int {
|
||||||
|
val parts = ver.split(".")
|
||||||
|
if(parts.size == 2) {
|
||||||
|
// 26.1 and above
|
||||||
|
return parts[0].toInt() * 10000 + parts[1].toInt()
|
||||||
|
}
|
||||||
|
return parts[1].toInt() * 100 + parts[2].toInt()
|
||||||
|
}
|
||||||
|
|
||||||
version = "${mod.version}+$minecraft"
|
version = "${mod.version}+$minecraft"
|
||||||
group = mod.group
|
group = mod.group
|
||||||
base {
|
base {
|
||||||
@@ -59,6 +68,15 @@ dependencies {
|
|||||||
modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${mod.dep("fabric_version")}")
|
modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${mod.dep("fabric_version")}")
|
||||||
modImplementation("net.fabricmc:fabric-language-kotlin:1.13.10+kotlin.2.3.20")
|
modImplementation("net.fabricmc:fabric-language-kotlin:1.13.10+kotlin.2.3.20")
|
||||||
modApi("dev.architectury:architectury-fabric:${archversion}")
|
modApi("dev.architectury:architectury-fabric:${archversion}")
|
||||||
|
fun getTeamRebornEnergy(): String {
|
||||||
|
val curVer = minecraftVersionToNum(minecraft)
|
||||||
|
if (curVer < minecraftVersionToNum("1.20.5")) { return "3.0.0" }
|
||||||
|
if (curVer < minecraftVersionToNum("1.21.0")) { return "4.0.0" }
|
||||||
|
if (curVer < minecraftVersionToNum("1.21.5")) { return "4.1.0" }
|
||||||
|
if (curVer < minecraftVersionToNum("26.1")) { return "4.2.0" }
|
||||||
|
return "5.0.0"
|
||||||
|
}
|
||||||
|
modApi("teamreborn:energy:${getTeamRebornEnergy()}")
|
||||||
}
|
}
|
||||||
if (loader == "forge") {
|
if (loader == "forge") {
|
||||||
"forge"("net.minecraftforge:forge:${minecraft}-${mod.dep("forge_loader")}")
|
"forge"("net.minecraftforge:forge:${minecraft}-${mod.dep("forge_loader")}")
|
||||||
@@ -83,6 +101,7 @@ dependencies {
|
|||||||
if (minecraft=="1.21.9" || minecraft=="1.21.11") modApi("dev.architectury:architectury-neoforge:${archversion}")
|
if (minecraft=="1.21.9" || minecraft=="1.21.11") modApi("dev.architectury:architectury-neoforge:${archversion}")
|
||||||
else modApi("dev.architectury:architectury-forge:${archversion}") // NOTE: this could be wrong
|
else modApi("dev.architectury:architectury-forge:${archversion}") // NOTE: this could be wrong
|
||||||
implementation("thedarkcolour:kotlinforforge-neoforge:6.0.0")
|
implementation("thedarkcolour:kotlinforforge-neoforge:6.0.0")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildscript {
|
buildscript {
|
||||||
|
|||||||
@@ -4,40 +4,35 @@ import net.minecraft.core.BlockPos
|
|||||||
import net.minecraft.network.chat.ChatType
|
import net.minecraft.network.chat.ChatType
|
||||||
import net.minecraft.network.chat.OutgoingChatMessage
|
import net.minecraft.network.chat.OutgoingChatMessage
|
||||||
import net.minecraft.network.chat.PlayerChatMessage
|
import net.minecraft.network.chat.PlayerChatMessage
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.util.RandomSource
|
|
||||||
import net.minecraft.world.InteractionHand
|
|
||||||
import net.minecraft.world.InteractionResult
|
import net.minecraft.world.InteractionResult
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.EntityBlock
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.world.level.redstone.Orientation
|
||||||
import net.minecraft.world.phys.BlockHitResult
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
import org.neoflock.neocomputers.entity.BlockEntities
|
import org.neoflock.neocomputers.entity.BlockEntities
|
||||||
import org.neoflock.neocomputers.entity.NodeEntity
|
|
||||||
import org.neoflock.neocomputers.network.Networking
|
import org.neoflock.neocomputers.network.Networking
|
||||||
|
import org.neoflock.neocomputers.network.PowerRole
|
||||||
|
|
||||||
class CapacitorEntity(pos: BlockPos, state: BlockState) : NodeEntity(BlockEntities.CAPACITOR_ENTITY.get(), pos, state) {
|
class CapacitorEntity(pos: BlockPos, state: BlockState) : NodeBlockEntity(BlockEntities.CAPACITOR_ENTITY.get(), pos, state) {
|
||||||
var amountStored: Double = 0.0
|
var amountStored: Double = 0.0
|
||||||
val capacity = 20000.0
|
val capacity = 20000.0
|
||||||
|
|
||||||
val netNode = object : Networking.Node() {
|
override val node = object : Networking.Node() {
|
||||||
override fun isProducer() = true
|
override fun getPowerRole() = PowerRole.PRODUCER
|
||||||
override fun getEnergy() = amountStored
|
override fun getEnergy() = amountStored
|
||||||
override fun maxEnergyCapacity(): Double = capacity
|
override fun maxEnergyCapacity(): Double = capacity
|
||||||
override fun setEnergy(energy: Double) {
|
override fun setEnergy(energy: Double) {
|
||||||
amountStored = energy
|
amountStored = energy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNode() = netNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CapacitorBlock : BaseBlock("capacitor"), EntityBlock {
|
class CapacitorBlock : NodeBlock("capacitor") {
|
||||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||||
val cap = CapacitorEntity(blockPos, blockState)
|
val cap = CapacitorEntity(blockPos, blockState)
|
||||||
cap.initNetworking()
|
cap.initNetworking()
|
||||||
@@ -57,7 +52,7 @@ class CapacitorBlock : BaseBlock("capacitor"), EntityBlock {
|
|||||||
if(ent.isPresent()) {
|
if(ent.isPresent()) {
|
||||||
val cap = ent.get()
|
val cap = ent.get()
|
||||||
if(sp.isCrouching()) cap.amountStored++
|
if(sp.isCrouching()) cap.amountStored++
|
||||||
val msg = PlayerChatMessage.system("energy: ${cap.amountStored} / ${cap.capacity} (${cap.getReachableNodes().size} reachable, ${cap.getNode().getReachable().size} connected)")
|
val msg = PlayerChatMessage.system("energy: ${cap.amountStored} / ${cap.capacity} (${cap.computeEdges().size} edges, ${cap.node.getReachable().size} connected)")
|
||||||
sp.sendChatMessage(OutgoingChatMessage.create(msg), false, ChatType.bind(ChatType.CHAT, player))
|
sp.sendChatMessage(OutgoingChatMessage.create(msg), false, ChatType.bind(ChatType.CHAT, player))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
123
src/main/kotlin/org/neoflock/neocomputers/block/NodeBlock.kt
Normal file
123
src/main/kotlin/org/neoflock/neocomputers/block/NodeBlock.kt
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package org.neoflock.neocomputers.block
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.world.level.redstone.Orientation
|
||||||
|
import org.neoflock.neocomputers.network.Networking
|
||||||
|
|
||||||
|
abstract class NodeBlockEntity(blockEntityType: BlockEntityType<*>, blockPos: BlockPos, blockState: BlockState) : BlockEntity(blockEntityType, blockPos, blockState) {
|
||||||
|
abstract val node: Networking.Node
|
||||||
|
|
||||||
|
fun initNetworking() {
|
||||||
|
Networking.addNode(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var stateIsDirty = true
|
||||||
|
|
||||||
|
open fun getNeighbourEntities(): List<BlockEntity> {
|
||||||
|
val subpos = listOf(
|
||||||
|
blockPos.offset(0, 0, 1),
|
||||||
|
blockPos.offset(0, 0, -1),
|
||||||
|
blockPos.offset(0, 1, 0),
|
||||||
|
blockPos.offset(0, -1, 0),
|
||||||
|
blockPos.offset(1, 0, 0),
|
||||||
|
blockPos.offset(-1, 0, 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
return subpos.mapNotNull { pos -> level?.getBlockEntity(pos) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun computeEdges(): Set<NodeBlockEntity> {
|
||||||
|
val s = mutableSetOf<NodeBlockEntity>()
|
||||||
|
val neighbours = getNeighbourEntities()
|
||||||
|
for(neighbour in neighbours) {
|
||||||
|
if(neighbour is NodeBlockEntity) s.add(neighbour);
|
||||||
|
// TODO: handle cable entities
|
||||||
|
}
|
||||||
|
s.remove(this)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
fun invalidateNodeState() {
|
||||||
|
stateIsDirty = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun needsSynchronization() = stateIsDirty
|
||||||
|
|
||||||
|
fun ensureSynchronized() {
|
||||||
|
if(!stateIsDirty) return
|
||||||
|
stateIsDirty = false
|
||||||
|
computeEdges().forEach {
|
||||||
|
node.connectTo(it.node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChanged() {
|
||||||
|
invalidateNodeState()
|
||||||
|
computeEdges().forEach { it.invalidateNodeState() }
|
||||||
|
super.setChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
Networking.removeNode(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NodeBlock(name: String): BaseBlock(name), EntityBlock {
|
||||||
|
override fun <T : BlockEntity> getTicker(
|
||||||
|
level: Level,
|
||||||
|
blockState: BlockState,
|
||||||
|
blockEntityType: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
return object : BlockEntityTicker<T> {
|
||||||
|
override fun tick(level: Level, blockPos: BlockPos, blockState: BlockState, blockEntity: T) {
|
||||||
|
if(blockEntity !is NodeBlockEntity) return;
|
||||||
|
blockEntity.ensureSynchronized()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPlacedBy(
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
blockState: BlockState,
|
||||||
|
livingEntity: LivingEntity?,
|
||||||
|
itemStack: ItemStack
|
||||||
|
) {
|
||||||
|
if(!level.isClientSide) {
|
||||||
|
val ent = level.getBlockEntity(blockPos)
|
||||||
|
if(ent is NodeBlockEntity) {
|
||||||
|
ent.invalidateNodeState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setPlacedBy(level, blockPos, blockState, livingEntity, itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun neighborChanged(
|
||||||
|
blockState: BlockState,
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
block: Block,
|
||||||
|
orientation: Orientation?,
|
||||||
|
bl: Boolean
|
||||||
|
) {
|
||||||
|
if(!level.isClientSide) {
|
||||||
|
val ent = level.getBlockEntity(blockPos)
|
||||||
|
if(ent is NodeBlockEntity) {
|
||||||
|
ent.invalidateNodeState()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
super.neighborChanged(blockState, level, blockPos, block, orientation, bl)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import org.neoflock.neocomputers.entity.ScreenEntity
|
|||||||
import org.neoflock.neocomputers.gui.menu.Menus
|
import org.neoflock.neocomputers.gui.menu.Menus
|
||||||
import org.neoflock.neocomputers.network.Networking
|
import org.neoflock.neocomputers.network.Networking
|
||||||
|
|
||||||
class ScreenBlock() : BaseBlock("screen"), EntityBlock {
|
class ScreenBlock() : NodeBlock("screen") {
|
||||||
|
|
||||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||||
val scr = ScreenEntity(blockPos, blockState)
|
val scr = ScreenEntity(blockPos, blockState)
|
||||||
@@ -39,7 +39,7 @@ class ScreenBlock() : BaseBlock("screen"), EntityBlock {
|
|||||||
): InteractionResult {
|
): InteractionResult {
|
||||||
if(!level.isClientSide) {
|
if(!level.isClientSide) {
|
||||||
val screenState = level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get()
|
val screenState = level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get()
|
||||||
if(!screenState.getNode().consumeEnergy(5.0)) return InteractionResult.SUCCESS;
|
if(!screenState.node.consumeEnergy(5.0)) return InteractionResult.SUCCESS;
|
||||||
MenuRegistry.openMenu(player as ServerPlayer, object : MenuProvider {
|
MenuRegistry.openMenu(player as ServerPlayer, object : MenuProvider {
|
||||||
override fun getDisplayName(): Component = Component.literal("SCREEEEEN!")
|
override fun getDisplayName(): Component = Component.literal("SCREEEEEN!")
|
||||||
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
|
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
package org.neoflock.neocomputers.entity;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import org.neoflock.neocomputers.network.Networking
|
|
||||||
|
|
||||||
open class NodeEntity(blockEntityType: BlockEntityType<*>, blockPos: BlockPos, blockState: BlockState) :
|
|
||||||
BlockEntity(blockEntityType, blockPos, blockState) {
|
|
||||||
|
|
||||||
// stuff
|
|
||||||
open fun getNode(): Networking.Node? = null
|
|
||||||
|
|
||||||
open fun getSubnodes(): List<Networking.Node> = listOf()
|
|
||||||
|
|
||||||
fun initNetworking() {
|
|
||||||
val node = getNode()
|
|
||||||
if(node != null) Networking.addNode(node)
|
|
||||||
getSubnodes().forEach { Networking.addNode(it) }
|
|
||||||
syncReachable()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun getDirectConnections(): List<NodeEntity> {
|
|
||||||
if(level == null) return listOf();
|
|
||||||
val offs = listOf(
|
|
||||||
BlockPos(0, 1, 0),
|
|
||||||
BlockPos(0, -1, 0),
|
|
||||||
BlockPos(1, 0, 0),
|
|
||||||
BlockPos(-1, 0, 0),
|
|
||||||
BlockPos(0, 0, 1),
|
|
||||||
BlockPos(0, 0, -1),
|
|
||||||
)
|
|
||||||
val entities = mutableListOf<NodeEntity>()
|
|
||||||
offs.forEach {
|
|
||||||
val ent = level?.getBlockEntity(blockPos.offset(it.x, it.y, it.z))
|
|
||||||
if(ent is NodeEntity) {
|
|
||||||
entities.add(ent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entities
|
|
||||||
}
|
|
||||||
|
|
||||||
// may include itself
|
|
||||||
fun getReachableNodes(): Set<Networking.Node> {
|
|
||||||
val visited = mutableSetOf<NodeEntity>()
|
|
||||||
val working = mutableListOf<NodeEntity>(this)
|
|
||||||
val nodes = mutableSetOf<Networking.Node>()
|
|
||||||
|
|
||||||
while(working.isNotEmpty()) {
|
|
||||||
val cur = working.removeFirst()
|
|
||||||
if(cur in visited) continue
|
|
||||||
visited.add(cur)
|
|
||||||
val n = cur.getNode()
|
|
||||||
if(n != null) {
|
|
||||||
// rely on the defined direct connections of the node
|
|
||||||
nodes.add(n)
|
|
||||||
if(n != this.getNode()) continue
|
|
||||||
}
|
|
||||||
working.addAll(cur.getDirectConnections());
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
fun syncReachable() {
|
|
||||||
val reachable = getReachableNodes().toList()
|
|
||||||
val node = getNode()
|
|
||||||
// nothing to sync
|
|
||||||
if(node == null) return
|
|
||||||
|
|
||||||
reachable.filter {
|
|
||||||
it !in node.connections
|
|
||||||
}.forEach {
|
|
||||||
node.connectTo(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
node.connections.filter { it !in reachable }.forEach {
|
|
||||||
node.disconnectFrom(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setChanged() {
|
|
||||||
super.setChanged()
|
|
||||||
syncReachable()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setRemoved() {
|
|
||||||
super.setRemoved()
|
|
||||||
syncReachable()
|
|
||||||
val n = getNode()
|
|
||||||
if(n != null) Networking.removeNode(n)
|
|
||||||
getSubnodes().forEach { Networking.removeNode(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +1,22 @@
|
|||||||
package org.neoflock.neocomputers.entity;
|
package org.neoflock.neocomputers.entity;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import org.neoflock.neocomputers.block.NodeBlockEntity
|
||||||
import org.neoflock.neocomputers.network.Networking
|
import org.neoflock.neocomputers.network.Networking
|
||||||
|
import org.neoflock.neocomputers.network.PowerRole
|
||||||
|
|
||||||
class ScreenEntity(blockPos: BlockPos, blockState: BlockState) :
|
class ScreenEntity(blockPos: BlockPos, blockState: BlockState) :
|
||||||
NodeEntity(BlockEntities.SCREEN_ENTITY.get(), blockPos, blockState) {
|
NodeBlockEntity(BlockEntities.SCREEN_ENTITY.get(), blockPos, blockState) {
|
||||||
|
|
||||||
var energyStored: Double = 0.0
|
var energyStored: Double = 0.0
|
||||||
|
|
||||||
val scrnod = object : Networking.Node() {
|
override val node = object : Networking.Node() {
|
||||||
|
override fun getPowerRole() = PowerRole.CONSUMER
|
||||||
override fun getEnergy() = energyStored
|
override fun getEnergy() = energyStored
|
||||||
override fun setEnergy(energy: Double) {
|
override fun setEnergy(energy: Double) {
|
||||||
energyStored = energy
|
energyStored = energy
|
||||||
}
|
}
|
||||||
override fun maxEnergyCapacity(): Double = 10.0
|
override fun maxEnergyCapacity(): Double = 10.0
|
||||||
override fun isConsumer() = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stuff
|
|
||||||
override fun getNode() = scrnod
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,15 @@ import kotlin.math.min
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
enum class PowerRole {
|
||||||
|
// consumes energy, wants to be fully charged
|
||||||
|
// does not give energy to network nodes
|
||||||
|
CONSUMER,
|
||||||
|
// produces/stores energy, will not care to charge itself
|
||||||
|
// will happily give energy to network nodes
|
||||||
|
PRODUCER,
|
||||||
|
}
|
||||||
|
|
||||||
object Networking {
|
object Networking {
|
||||||
// maximum amount of hops between nodes
|
// maximum amount of hops between nodes
|
||||||
var maxHopCount = 32
|
var maxHopCount = 32
|
||||||
@@ -21,6 +30,7 @@ object Networking {
|
|||||||
NETWORK,
|
NETWORK,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class Message(val sender: Node)
|
abstract class Message(val sender: Node)
|
||||||
|
|
||||||
class ClassicPacket(sender: Node, val src: String, val dst: String, val port: Int, val data: List<Any>, val hopCount: Int) : Message(sender) {
|
class ClassicPacket(sender: Node, val src: String, val dst: String, val port: Int, val data: List<Any>, val hopCount: Int) : Message(sender) {
|
||||||
@@ -33,16 +43,15 @@ object Networking {
|
|||||||
|
|
||||||
open class Node {
|
open class Node {
|
||||||
val connections = mutableSetOf<Node>()
|
val connections = mutableSetOf<Node>()
|
||||||
val reachability = Visibility.NETWORK
|
private var reachableCache: Set<Node>? = null
|
||||||
var reachableCache: Set<Node>? = null
|
|
||||||
|
|
||||||
open fun isProducer(): Boolean = false
|
open fun getReachability() = Visibility.NETWORK
|
||||||
open fun isConsumer(): Boolean = false
|
open fun getPowerRole() = PowerRole.CONSUMER
|
||||||
open fun getEnergy(): Double = 0.0
|
open fun getEnergy(): Double = 0.0
|
||||||
open fun setEnergy(energy: Double) {}
|
open fun setEnergy(energy: Double) {}
|
||||||
|
|
||||||
open fun maxEnergyCapacity(): Double = 0.0
|
open fun maxEnergyCapacity(): Double = 0.0
|
||||||
fun getChargerNodes(): Set<Node> = getReachable().filter { it.isProducer() }.toSet()
|
fun getChargerNodes(): Set<Node> = getReachable().filter { it.getPowerRole() == PowerRole.PRODUCER }.toSet()
|
||||||
fun totalEnergyInConnections(): Double = getChargerNodes().fold(0.0) { acc, node -> acc + node.getEnergy() }
|
fun totalEnergyInConnections(): Double = getChargerNodes().fold(0.0) { acc, node -> acc + node.getEnergy() }
|
||||||
fun maxEnergyInConnections(): Double = getChargerNodes().fold(0.0) { acc, node -> acc + node.maxEnergyCapacity() }
|
fun maxEnergyInConnections(): Double = getChargerNodes().fold(0.0) { acc, node -> acc + node.maxEnergyCapacity() }
|
||||||
|
|
||||||
@@ -82,7 +91,7 @@ object Networking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun tick() {
|
open fun tick() {
|
||||||
if(isConsumer()) tryToChargeFully()
|
if(getPowerRole() == PowerRole.CONSUMER) tryToChargeFully()
|
||||||
}
|
}
|
||||||
// processes a received message
|
// processes a received message
|
||||||
open fun received(message: Message) {}
|
open fun received(message: Message) {}
|
||||||
@@ -109,12 +118,17 @@ object Networking {
|
|||||||
return reachableCache!!;
|
return reachableCache!!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun invalidateReachableCache() {
|
||||||
|
reachableCache = null
|
||||||
|
}
|
||||||
|
|
||||||
fun computeReachable(): Set<Node> {
|
fun computeReachable(): Set<Node> {
|
||||||
|
val reachability = getReachability()
|
||||||
if(reachability == Visibility.NONE) {
|
if(reachability == Visibility.NONE) {
|
||||||
return setOf();
|
return setOf();
|
||||||
}
|
}
|
||||||
if(reachability == Visibility.DIRECT) {
|
if(reachability == Visibility.DIRECT) {
|
||||||
return connections;
|
return connections.minus(this);
|
||||||
}
|
}
|
||||||
if(reachability == Visibility.NETWORK) {
|
if(reachability == Visibility.NETWORK) {
|
||||||
// absolute cinema
|
// absolute cinema
|
||||||
@@ -167,7 +181,7 @@ object Networking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DebugBatteryNode(var power: Double, val capacity: Double): Node() {
|
class DebugBatteryNode(var power: Double, val capacity: Double): Node() {
|
||||||
override fun isProducer() = true
|
override fun getPowerRole() = PowerRole.PRODUCER
|
||||||
override fun maxEnergyCapacity() = capacity
|
override fun maxEnergyCapacity() = capacity
|
||||||
override fun getEnergy() = power
|
override fun getEnergy() = power
|
||||||
override fun setEnergy(energy: Double) { power = energy }
|
override fun setEnergy(energy: Double) { power = energy }
|
||||||
|
|||||||
Reference in New Issue
Block a user