Syntax: Select all
def player_hurt(event):
print('Userid: {0}'.format(event.get_int('userid'))
print('Weapon: {0}'.format(event.get_string('weapon'))
To be honest, I've always hated it. Python has insanely powerful dictionaries, which can do much more than the current GameEvent objects. I'm suggesting we finally try and bring dictionaries to the event system:
Syntax: Select all
def player_hurt(eargs): # eargs as in event arguments
print('Userid: {0}'.format(eargs['userid']))
print('Weapon: {0}'.format(eargs['weapon']))
And of course since it's a dictionary now, you can do all kinds of cool stuff with it:
Syntax: Select all
def player_hurt(eargs):
print('Userid: {userid}\nWeapon: {weapon}'.format(**eargs))
And if we were to use the double star syntax, which I would love to see, you could grab any values you want already in the parameters, and the rest would get packed into the eargs dict:
Syntax: Select all
def player_hurt(userid, victim, **eargs):
print('Attacker: {0}, Victim: {1}, Eargs: {3}'.format(userid, victim, eargs))
There was already a discussion about this long ago: http://forums.sourcepython.com/showthread.php?10-Event-system-discussion but since SP has developed a lot from then, I believe we now have better ways of doing this than manually going through every argument. I tried to get my head around it and come up with some kind of hacky try/except as Ayuto suggested in the old thread, but it really wasn't that good. Luckily, Ayuto had a better solution already: http://pastebin.com/U36XQt8U
Using this KeyValues trick, I was able to replicate the suggested behaviour purely on Python:
Syntax: Select all
from collections import defaultdict
from events import Event
from memory import get_object_pointer
from memory import make_object
from keyvalues import KeyValues
OFFSET = 8
class DictEvent(object):
_callbacks = defaultdict(list)
@staticmethod
def fire(event_name, event_arguments):
for callback in DictEvent._callbacks[event_name]:
callback(**event_arguments)
def __init__(self, *event_names):
self._event_names = event_names
def __call__(self, *callbacks):
for callback in callbacks:
for event_name in self._event_names:
if callback not in DictEvent._callbacks[event_name]:
DictEvent._callbacks[event_name].append(callback)
@Event('player_spawn', ..., 'player_death') # You'd want to automatically register all events here
def on_event(event):
pointer = get_object_pointer(event).get_pointer(OFFSET)
keys = make_object(KeyValues, pointer)
event_arguments = keys.as_dict()
DictEvent.fire(event.get_name(), event_arguments)
Now simply instead of using the @Event decorator, one would use @DictEvent decorator:
Syntax: Select all
@DictEvent('player_spawn')
def on_spawn(userid, **eargs):
print(userid, eargs)
What do you guys think?