diff --git a/actor-typed-tests/src/test/scala/org/apache/pekko/actor/typed/BehaviorSpec.scala b/actor-typed-tests/src/test/scala/org/apache/pekko/actor/typed/BehaviorSpec.scala index 355b50c09e8..47acbd0cd0b 100644 --- a/actor-typed-tests/src/test/scala/org/apache/pekko/actor/typed/BehaviorSpec.scala +++ b/actor-typed-tests/src/test/scala/org/apache/pekko/actor/typed/BehaviorSpec.scala @@ -378,6 +378,22 @@ class ReceiveBehaviorSpec extends Messages with BecomeWithLifecycle with Stoppab } } +class ReceiveMessageWithSameBehaviorSpec extends Messages { + override def behavior(monitor: ActorRef[Event]): (Behavior[Command], Aux) = behv(monitor) -> null + private def behv(monitor: ActorRef[Event]): Behavior[Command] = { + SBehaviors + .receiveMessageWithSame[Command] { + case Miss => + monitor ! Missed + case Ignore => + monitor ! Ignored + case Ping => + monitor ! Pong + case _ => + } + } +} + class ImmutableWithSignalScalaBehaviorSpec extends Messages with BecomeWithLifecycle with Stoppable { override def behavior(monitor: ActorRef[Event]): (Behavior[Command], Aux) = behv(monitor) -> null diff --git a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala index 57a57d89796..c9d4facd350 100644 --- a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala +++ b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala @@ -143,6 +143,29 @@ object Behaviors { def receiveMessage[T](onMessage: pekko.japi.Function[T, Behavior[T]]): Behavior[T] = new BehaviorImpl.ReceiveBehavior((_, msg) => onMessage.apply(msg)) + /** + * Simplified version of [[receiveMessage]] with only a single argument - the message + * to be handled, but it doesn't produce a return value of next behavior. + * Useful for when the behavior doesn't want to change in runtime. + * + * Construct an actor behavior that can react to incoming messages but not to + * lifecycle signals. After spawning this actor from another actor (or as the + * guardian of an [[pekko.actor.typed.ActorSystem]]) it will be executed within an + * [[ActorContext]] that allows access to the system, spawning and watching + * other actors, etc. + * + * Compared to using [[AbstractBehavior]] this factory is a more functional style + * of defining the `Behavior`. Processing the next message will not result in + * different behavior than this one + * + * @since 1.1.0 + */ + def receiveMessageWithSame[T](onMessage: pekko.japi.Procedure[T]): Behavior[T] = + new BehaviorImpl.ReceiveBehavior((_, msg) => { + onMessage.apply(msg) + same[T] + }) + /** * Construct an actor behavior that can react to both incoming messages and * lifecycle signals. After spawning this actor from another actor (or as the diff --git a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/scaladsl/Behaviors.scala b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/scaladsl/Behaviors.scala index cab2654a5e4..93c71616c78 100644 --- a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/scaladsl/Behaviors.scala +++ b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/scaladsl/Behaviors.scala @@ -133,6 +133,27 @@ object Behaviors { def receiveMessage[T](onMessage: T => Behavior[T]): Receive[T] = new ReceiveMessageImpl(onMessage) + /** + * Simplified version of [[receiveMessage]] with only a single argument - the message + * to be handled, but it doesn't produce a return value of next behavior. + * Useful for when the behavior doesn't want to change in runtime. + * + * Construct an actor behavior that can react to incoming messages but not to + * lifecycle signals. After spawning this actor from another actor (or as the + * guardian of an [[pekko.actor.typed.ActorSystem]]) it will be executed within an + * [[ActorContext]] that allows access to the system, spawning and watching + * other actors, etc. + * + * Compared to using [[AbstractBehavior]] this factory is a more functional style + * of defining the `Behavior`. Processing the next message will not result in + * different behavior than this one + * + * @since 1.1.0 + */ + def receiveMessageWithSame[T](onMessage: T => Unit): Receive[T] = { + new ReceiveMessageImpl(onMessage.andThen(_ => same)) + } + /** * Construct an actor `Behavior` from a partial message handler which treats undefined messages as unhandled. */