Skamah One
Skamah One

Reputation: 2456

Better logic for firing events and doing the actual event?

Below I have a simple class with some events in it. Don't worry about the Event class, it's flawless.

class Warrior:
    def __init__(self, health, damage):
        self.health = health
        self.damage = damage
        # events
        self.e_hurt = Event()
        self.e_attack = Event()

    def hurt(self, damage):
        self.health -= damage
        self.e_hurt.fire()

    def attack(self, target):
        target.hurt(self.damage)
        self.e_attack.fire()

What I can't figure out is where to fire my events. It makes most sense to fire e_hurt event after the warrior was hurt, and e_attack event after the warrior has attacked. However, this results into victim.e_hurt getting fired before attacker.e_attack, when attacker attacks victim:

def on_hurt():
    print "Someone was hurt."

def on_attack():
    print "Someone attacked."

def main():
    victim = Warrior(50, 0)
    victim.e_hurt.subscribe(on_hurt)
    attacker = Warrior(50, 20)
    attacker.e_attack.subscribe(on_attack)
    attacker.attack(victim)

The two events get outputted in the "wrong" (programmatically correct, but semantically wrong) order:

 Someone was hurt.
 Someone attacked.

Obviously the warrior has to attack before the other warrior can get hurt. Of course I could just change the attack-method to look like this:

def attack(self, target):
    self.e_attack.fire()
    target.hurt(self.damage)

But it doesn't feel right to raise an attack event before the actual attack happens, and some other events might need to be called after the attack.

The only actual solution I can think of is to have two events (before_attack and after_attack) but is there a better solution that wouldn't need two events for one actual event (attacking)?

Upvotes: 2

Views: 52

Answers (1)

unutbu
unutbu

Reputation: 879391

def attack(self, target):
    self.e_attack.fire()
    target.hurt(self.damage)

seems to make perfect sense to me. self first attacks, then the target gets hurt.

Upvotes: 2

Related Questions