You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.7 KiB
67 lines
1.7 KiB
package wow.doge.mygame.utils
|
|
|
|
import scala.concurrent.duration.FiniteDuration
|
|
import scala.util.Random
|
|
|
|
import akka.actor.typed.ActorRef
|
|
import akka.actor.typed.Behavior
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import akka.actor.typed.scaladsl.TimerScheduler
|
|
import wow.doge.mygame.implicits._
|
|
|
|
object GenericTimerActor {
|
|
sealed trait Command
|
|
case object Start extends Command
|
|
case object Stop extends Command
|
|
private case object Tick extends Command
|
|
case class TimerKey(seed: Long)
|
|
|
|
case class Props[T](
|
|
target: ActorRef[T],
|
|
messageToSend: T,
|
|
timeInterval: FiniteDuration
|
|
) {
|
|
def behavior =
|
|
Behaviors.withTimers[Command] { timers =>
|
|
Behaviors.setup { ctx =>
|
|
new GenericTimerActor(
|
|
ctx,
|
|
timers,
|
|
TimerKey(Random.nextLong()),
|
|
this
|
|
).idle
|
|
}
|
|
}
|
|
}
|
|
}
|
|
class GenericTimerActor[T](
|
|
ctx: ActorContext[GenericTimerActor.Command],
|
|
timers: TimerScheduler[GenericTimerActor.Command],
|
|
timerKey: GenericTimerActor.TimerKey,
|
|
props: GenericTimerActor.Props[T]
|
|
) {
|
|
import GenericTimerActor._
|
|
|
|
val idle: Behavior[Command] =
|
|
Behaviors.receiveMessage {
|
|
case Start =>
|
|
timers.startTimerWithFixedDelay(timerKey, Tick, props.timeInterval)
|
|
active
|
|
case _ => Behaviors.unhandled
|
|
|
|
}
|
|
|
|
val active: Behavior[Command] =
|
|
Behaviors.receiveMessage {
|
|
case Start =>
|
|
ctx.log.warnP(s"Timer-${timerKey.seed}: Timer already started")
|
|
Behaviors.same
|
|
case Tick =>
|
|
props.target ! props.messageToSend
|
|
Behaviors.same
|
|
case Stop =>
|
|
timers.cancel(timerKey)
|
|
idle
|
|
}
|
|
}
|