aura effects that will run for longer will not get replaced by aura effects that would end sooner

This commit is contained in:
FateJH 2020-08-20 09:22:22 -04:00
parent f627571f0e
commit ac5e26f37a
2 changed files with 73 additions and 11 deletions

View file

@ -23,7 +23,7 @@ trait AuraEffectBehavior {
* key - aura effect; value - the timer for that effect
* @see `ApplicableEffect`
*/
private val effectToTimer: mutable.HashMap[Aura, Cancellable] = mutable.HashMap.empty[Aura, Cancellable]
private val effectToTimer: mutable.HashMap[Aura, AuraEffectBehavior.Entry] = mutable.HashMap.empty[Aura, AuraEffectBehavior.Entry]
def AuraTargetObject: AuraEffectBehavior.Target
@ -44,7 +44,7 @@ trait AuraEffectBehavior {
*/
def ApplicableEffect(effect: Aura): Unit = {
//create entry
effectToTimer += effect -> Default.Cancellable
effectToTimer += effect -> AuraEffectBehavior.Entry()
}
/**
@ -67,27 +67,29 @@ trait AuraEffectBehavior {
/**
* As long as the effect has been approved for this target,
* the timer will either start if it is stopped or has never been started,
* or the timer will stop and be recreated with the new duration if is currently running.
* or the timer will stop and be recreated with the new duration if is currently running for a shoreter amount of time.
* @param effect the effect to be emitted
* @param duration for how long the effect will be emitted
* @return `true`, if the timer was started or restarted;
* `false`, otherwise
*/
private def StartAuraTimer(effect: Aura, duration: Long): Boolean = {
//pair aura effect with id
//pair aura effect with entry
(effectToTimer.get(effect) match {
case None =>
None
case Some(timer) =>
case Some(timer) if timer.start + timer.duration < System.currentTimeMillis() + duration =>
timer.cancel()
Some(effect)
case _ =>
None
}) match {
case None =>
false
case Some(_) =>
//paired id with timer; retime
effectToTimer(effect) =
//retime
effectToTimer(effect) = AuraEffectBehavior.Entry(
duration,
context.system.scheduler.scheduleOnce(duration milliseconds, self, AuraEffectBehavior.EndEffect(effect))
)
true
}
}
@ -102,7 +104,7 @@ trait AuraEffectBehavior {
effectToTimer.get(effect) match {
case Some(timer) if !timer.isCancelled =>
timer.cancel()
effectToTimer(effect) = Default.Cancellable
//effectToTimer(effect) = Default.Cancellable
AuraTargetObject.RemoveEffectFromAura(effect)
true
case _ =>
@ -116,7 +118,7 @@ trait AuraEffectBehavior {
def EndAllEffects() : Unit = {
effectToTimer.keysIterator.foreach { effect =>
effectToTimer(effect).cancel()
effectToTimer(effect) = Default.Cancellable
//effectToTimer(effect) = Default.Cancellable
}
val obj = AuraTargetObject
obj.Aura.foreach { obj.RemoveEffectFromAura }
@ -164,6 +166,18 @@ trait AuraEffectBehavior {
object AuraEffectBehavior {
type Target = PlanetSideServerObject with AuraContainer
case class Entry(duration: Long, timer: Cancellable) extends Cancellable {
val start: Long = System.currentTimeMillis()
override def isCancelled : Boolean = timer.isCancelled
override def cancel: Boolean = timer.cancel
}
object Entry {
def apply(): Entry = Entry(0, Default.Cancellable)
}
final case class StartEffect(effect: Aura, duration: Long)
final case class EndEffect(aura: Aura)

View file

@ -116,6 +116,31 @@ class AuraEffectBehaviorStartEffectTest extends ActorTest {
}
}
class AuraEffectBehaviorStartLongerEffectTest extends ActorTest {
val obj = new AuraTest.Entity()
val updateProbe = new TestProbe(system)
obj.Actor = system.actorOf(Props(classOf[AuraTest.Agency], obj, updateProbe.ref), "aura-test-actor")
"AuraEffectBehavior" should {
"replace a shorter effect with a longer one" in {
assert(obj.Aura.isEmpty)
obj.Actor ! AuraEffectBehavior.StartEffect(Aura.Plasma, 500)
val msg1 = updateProbe.receiveOne(100 milliseconds)
assert(
msg1 match {
case AuraTest.DoUpdateAuraEffect() => true
case _ => false
}
)
assert(obj.Aura.contains(Aura.Plasma))
obj.Actor ! AuraEffectBehavior.StartEffect(Aura.Plasma, 2500)
updateProbe.expectNoMessage(2000 milliseconds)
//first effect has not ended naturally (yet)
assert(obj.Aura.contains(Aura.Plasma))
}
}
}
class AuraEffectBehaviorNoRedundantStartEffectTest extends ActorTest {
val obj = new AuraTest.Entity()
val updateProbe = new TestProbe(system)
@ -137,6 +162,29 @@ class AuraEffectBehaviorNoRedundantStartEffectTest extends ActorTest {
assert(obj.Aura.contains(Aura.Plasma))
obj.Actor ! AuraEffectBehavior.StartEffect(Aura.Plasma, 2500)
updateProbe.expectNoMessage(1500 milliseconds)
}
}
}
class AuraEffectBehaviorNoOverrideStartEffectTest extends ActorTest {
val obj = new AuraTest.Entity()
val updateProbe = new TestProbe(system)
obj.Actor = system.actorOf(Props(classOf[AuraTest.Agency], obj, updateProbe.ref), "aura-test-actor")
"AuraEffectBehavior" should {
"not replace a long-running effect with a short-running effect" in {
assert(obj.Aura.isEmpty)
obj.Actor ! AuraEffectBehavior.StartEffect(Aura.Plasma, 2500)
val msg1 = updateProbe.receiveOne(100 milliseconds)
assert(
msg1 match {
case AuraTest.DoUpdateAuraEffect() => true
case _ => false
}
)
assert(obj.Aura.contains(Aura.Plasma))
obj.Actor ! AuraEffectBehavior.StartEffect(Aura.Plasma, 500)
updateProbe.expectNoMessage(1500 milliseconds)
//effect has not ended naturally
assert(obj.Aura.contains(Aura.Plasma))
}