From 155a7fad1fff409cf91d6af6f613ed9b50fd21d7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 28 Apr 2019 13:23:27 +0200 Subject: feat: Add proper identify implementation for ActorRef --- .../odcsim/engine/omega/OmegaActorSystem.kt | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'odcsim-engine-omega/src') 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(root: Behavior, 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(root: Behavior, 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(root: Behavior, 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(root: Behavior, override val name: String) override fun send(ref: ActorRef, msg: U, after: Duration) = schedule(ref, msg, after) override fun spawn(behavior: Behavior, name: String): ActorRef { - val ref = ActorRefImpl(self.path.child(name)) + val ref = ActorRefImpl(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(root: Behavior, override val name: String) override fun hashCode(): Int = self.path.hashCode() } + /** + * Isolate uncaught exceptions originating from actor interpreter invocations. + */ private inline fun Actor.isolate(block: (Actor) -> U): U? { return try { block(this) @@ -232,12 +237,22 @@ class OmegaActorSystem(root: Behavior, 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(override val path: ActorPath) : ActorRef + /** + * Internal [ActorRef] implementation for this actor system. + */ + private data class ActorRefImpl(private val owner: OmegaActorSystem<*>, + override val path: ActorPath) : ActorRef { + 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. -- cgit v1.2.3