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

kreuzberg.Identifier.scala Maven / Gradle / Ivy

There is a newer version: 0.10.3
Show newest version
package kreuzberg

import kreuzberg.IdentifierFactory.instance

import java.util.concurrent.atomic.AtomicInteger

/** Some object which has an identifier. */
trait Identified {

  /** Id of this thing. */
  def id: Identifier

  /** Comment, which will probably built into into a tree. Can be disabled by returning "" */
  def comment: String = getClass.getSimpleName.stripSuffix("$")
}

/** Identifier for identifying things. */
opaque type Identifier = Int

object Identifier {
  def apply(id: Int): Identifier = id

  inline def next(): Identifier = IdentifierFactory.instance.next()

  extension (i: Identifier) {
    def value: Int = i
  }

  /** Anonymous root components, owner of root models. */
  val RootComponent = Identifier(0)
}

/** Builds identifiers. */
trait IdentifierFactory {
  def next(): Identifier
}

object IdentifierFactory {
  class Default extends IdentifierFactory {
    // 0 is reserved for Root Identifier!
    private val _nextValue = AtomicInteger(1)

    override def next(): Identifier = Identifier(_nextValue.getAndIncrement())
  }

  private val default = new Default()

  /** Per default we share one factory for all threads. */
  private val threadLocal = new SimpleThreadLocal[IdentifierFactory](default)

  def instance: IdentifierFactory = threadLocal.get()

  /** Execute some f with a fresh factory (e.g. testcases with semi-reliable ids) */
  def withFresh[T](f: => T): T = {
    using(new Default())(f)
  }

  /** Execute some block f with a specific factory. */
  def using[T](factory: IdentifierFactory)(f: => T): T = {
    val current = threadLocal.get()
    threadLocal.set(factory)
    try {
      f
    } finally {
      threadLocal.set(current)
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy