diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2019-04-28 13:23:27 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2019-05-13 20:26:47 +0200 |
| commit | 155a7fad1fff409cf91d6af6f613ed9b50fd21d7 (patch) | |
| tree | 3e774701da28aa9f49abf97ce6bd9751ddff3753 | |
| parent | 4e6920d5c128b49750408a11850dfa6a7abb1e9e (diff) | |
feat: Add proper identify implementation for ActorRef
| -rw-r--r-- | odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt | 4 | ||||
| -rw-r--r-- | odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt | 31 |
2 files changed, 26 insertions, 9 deletions
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt index 71b10325..3ba5ce76 100644 --- a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt @@ -24,10 +24,12 @@ package com.atlarge.odcsim +import java.io.Serializable + /** * A reference to an entity in simulation that accepts messages of type [T]. */ -interface ActorRef<in T : Any> { +interface ActorRef<in T : Any> : Comparable<ActorRef<*>>, Serializable { /** * The path for this actor (from this actor up to the root actor). */ diff --git a/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt index 566f1ff5..9899a360 100644 --- a/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt +++ b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt @@ -60,9 +60,9 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) override val path: ActorPath = ActorPath.Root(name = "/user") /** - * A flag to indicate the system has started. + * The state of the actor system. */ - private var state: ActorSystemState = ActorSystemState.PENDING + private var state: ActorSystemState = ActorSystemState.CREATED /** * The event queue to process @@ -90,7 +90,7 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) require(until >= .0) { "The given instant must be a non-negative number" } // Start the root actor on initial run - if (state == ActorSystemState.PENDING) { + if (state == ActorSystemState.CREATED) { registry[path]!!.isolate { it.start() } state = ActorSystemState.STARTED } else if (state == ActorSystemState.TERMINATED) { @@ -124,6 +124,8 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) registry[path]?.stop() } + override fun compareTo(other: ActorRef<*>): Int = path.compareTo(other.path) + /** * The identifier for the next message to be scheduled. */ @@ -145,7 +147,7 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) override fun <U : Any> send(ref: ActorRef<U>, msg: U, after: Duration) = schedule(ref, msg, after) override fun <U : Any> spawn(behavior: Behavior<U>, name: String): ActorRef<U> { - val ref = ActorRefImpl<U>(self.path.child(name)) + val ref = ActorRefImpl<U>(this@OmegaActorSystem, self.path.child(name)) if (ref.path !in registry) { val actor = Actor(ref, behavior) registry[ref.path] = actor @@ -221,6 +223,9 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) override fun hashCode(): Int = self.path.hashCode() } + /** + * Isolate uncaught exceptions originating from actor interpreter invocations. + */ private inline fun <T : Any, U> Actor<T>.isolate(block: (Actor<T>) -> U): U? { return try { block(this) @@ -232,12 +237,22 @@ class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) } } - - private enum class ActorSystemState { - PENDING, STARTED, TERMINATED + /** + * Enumeration to track the state of the actor system. + */ + private enum class ActorSystemState { + CREATED, STARTED, TERMINATED } - private inner class ActorRefImpl<T : Any>(override val path: ActorPath) : ActorRef<T> + /** + * Internal [ActorRef] implementation for this actor system. + */ + private data class ActorRefImpl<T : Any>(private val owner: OmegaActorSystem<*>, + override val path: ActorPath) : ActorRef<T> { + override fun toString(): String = "Actor[$path]" + + override fun compareTo(other: ActorRef<*>): Int = path.compareTo(other.path) + } /** * A wrapper around a message that has been scheduled for processing. |
