All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.unibo.alchemist.collektive.device.CollektiveDevice.kt Maven / Gradle / Ivy

The newest version!
package it.unibo.alchemist.collektive.device

import it.unibo.alchemist.model.Environment
import it.unibo.alchemist.model.Node
import it.unibo.alchemist.model.NodeProperty
import it.unibo.alchemist.model.Position
import it.unibo.alchemist.model.Time
import it.unibo.alchemist.model.molecules.SimpleMolecule
import it.unibo.collektive.aggregate.api.Aggregate
import it.unibo.collektive.aggregate.api.operators.neighboringViaExchange
import it.unibo.collektive.alchemist.device.sensors.EnvironmentVariables
import it.unibo.collektive.field.Field
import it.unibo.collektive.networking.InboundMessage
import it.unibo.collektive.networking.Network
import it.unibo.collektive.networking.OutboundMessage

/**
 * Representation of a Collektive device in Alchemist.
 * [P] is the position type, the [environment] property represent the environment in which the device is located,
 * the [node] property represent a node in the environment, [retainMessagesFor] is the time for which messages
 * are retained.
 */
class CollektiveDevice

( private val environment: Environment, override val node: Node, private val retainMessagesFor: Time? = null, ) : NodeProperty, Network, EnvironmentVariables, DistanceSensor where P : Position

{ private data class TimedMessage(val receivedAt: Time, val payload: InboundMessage) /** * The current time. */ var currentTime: Time = Time.ZERO /** * The ID of the node. */ val id = node.id private val validMessages: MutableList = mutableListOf() private fun receiveMessage( time: Time, message: InboundMessage, ) { validMessages += TimedMessage(time, message) } override fun Aggregate.distances(): Field = environment.getPosition(node).let { nodePosition -> neighboringViaExchange(nodePosition).map { position -> nodePosition.distanceTo(position) } } override fun cloneOnNewNode(node: Node): NodeProperty = CollektiveDevice(environment, node, retainMessagesFor) override fun read(): Collection> = when { validMessages.isEmpty() -> emptyList() retainMessagesFor == null -> validMessages.map { it.payload }.also { validMessages.clear() } else -> { validMessages.retainAll { it.receivedAt + retainMessagesFor >= currentTime } validMessages.map { it.payload } } } override fun write(message: OutboundMessage) { if (message.isNotEmpty()) { val neighboringNodes = environment.getNeighborhood(node) if (!neighboringNodes.isEmpty) { val neighborhood = neighboringNodes.mapNotNull { node -> @Suppress("UNCHECKED_CAST") node.properties.firstOrNull { it is CollektiveDevice<*> } as? CollektiveDevice

} neighborhood.forEach { neighbor -> neighbor.receiveMessage( currentTime, InboundMessage(message.senderId, message.messagesFor(neighbor.id)), ) } } } } @Suppress("UNCHECKED_CAST") override fun get(name: String): T = node.getConcentration(SimpleMolecule(name)) as T override fun getOrNull(name: String): T? = if (isDefined(name)) { get(name) } else { null } override fun getOrDefault( name: String, default: T, ): T = getOrNull(name) ?: default override fun isDefined(name: String): Boolean = node.contains(SimpleMolecule(name)) override fun set( name: String, value: T, ): T = value.also { node.setConcentration(SimpleMolecule(name), it) } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy