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

it.unibo.alchemist.model.neighborhoods.SimpleNeighborhood.kt Maven / Gradle / Ivy

Go to download

Abstract, incarnation independent implementations of the Alchemist's interfaces. Provides support for those who want to write incarnations.

There is a newer version: 35.0.1
Show newest version
/*
 * Copyright (C) 2010-2023, Danilo Pianini and contributors
 * listed, for each module, in the respective subproject's build.gradle.kts file.
 *
 * This file is part of Alchemist, and is distributed under the terms of the
 * GNU General Public License, with a linking exception,
 * as described in the file LICENSE in the Alchemist distribution's top directory.
 */
package it.unibo.alchemist.model.neighborhoods

import it.unibo.alchemist.model.Environment
import it.unibo.alchemist.model.Neighborhood
import it.unibo.alchemist.model.Node
import it.unibo.alchemist.model.Position
import it.unibo.alchemist.util.BugReporting.reportBug
import org.danilopianini.util.ArrayListSet
import org.danilopianini.util.Hashes
import org.danilopianini.util.ImmutableListSet
import org.danilopianini.util.ListSet
import org.danilopianini.util.ListSets

/**
 * A basic implementation of the [Neighborhood] interface.
 */
class SimpleNeighborhood> private constructor(
    private val environment: Environment,
    private val center: Node,
    private val neighbors: ImmutableListSet>,
) : Neighborhood {

    internal constructor(
        environment: Environment,
        center: Node,
        neighbors: Iterable>,
    ) : this(environment, center, ImmutableListSet.Builder>().addAll(neighbors).build())

    override fun clone() = SimpleNeighborhood(environment, center, ArrayListSet(neighbors))

    override fun contains(node: Node?) = neighbors.contains(node)

    override fun getCenter() = center

    override fun getNeighbors(): ListSet> = ListSets.unmodifiableListSet(neighbors)

    override fun isEmpty() = neighbors.isEmpty()

    override fun iterator() = neighbors.iterator()

    override fun size() = neighbors.size

    override fun toString() = "$center links: $neighbors"

    override fun equals(other: Any?): Boolean = other is SimpleNeighborhood<*, *> &&
        other.environment == environment &&
        other.center == center &&
        other.neighbors == neighbors

    override fun hashCode(): Int = Hashes.hash32(environment, center, neighbors)

    override fun add(node: Node) = SimpleNeighborhood(
        environment,
        center,
        Iterable {
            object : Iterator> {
                val previousNodes = neighbors.iterator()
                var nodeReady = true
                override fun hasNext() = nodeReady
                override fun next() = if (previousNodes.hasNext()) {
                    previousNodes.next()
                } else {
                    if (nodeReady) {
                        nodeReady = false
                        node
                    } else {
                        throw NoSuchElementException("No other elements.")
                    }
                }
            }
        },
    )

    override fun remove(node: Node): Neighborhood {
        require(node in this) {
            "$node not in $this"
        }
        return SimpleNeighborhood(
            environment,
            center,
            Iterable {
                object : Iterator> {
                    val base = neighbors.iterator()
                    var lookahead = updateLookAhead()
                    fun updateLookAhead(): Node? =
                        if (base.hasNext()) {
                            val maybeNext = base.next()
                            if (maybeNext == node) {
                                updateLookAhead()
                            } else {
                                maybeNext
                            }
                        } else {
                            null
                        }
                    override fun hasNext() = lookahead !== null
                    override fun next() =
                        if (hasNext()) {
                            val result = lookahead ?: reportBug(
                                "Neighborhood iterator failure in ${this::class.qualifiedName}",
                                mapOf(
                                    "base" to base,
                                    "lookahead" to lookahead,
                                    "hasNext" to hasNext(),
                                ),
                            )
                            lookahead = updateLookAhead()
                            result
                        } else {
                            throw NoSuchElementException("No other elements.")
                        }
                }
            },
        )
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy