Source

pygamekit / event.pxi


from libcpp cimport bool
from prerequisites cimport *

cdef class EventData(object):
    
    cdef int _key
    cdef gkVector2 *_rel
    cdef std_string *_prop
    
    def __init__(self):
        self._rel = new gkVector2()
        self._prop = new std_string()
        #TODO: is this being freed?
    
    @property
    def keycode(self):
        return self._key
    
    @property
    def keyname(self):
        return KEYS[self._key]
        
    @property
    def pos(self):
        cdef gkVector2 v = getMouse().getPosition()
        return v.x, v.y
        
    @property
    def rel(self):
        return self._rel.x, self._rel.y
        

cdef class Event(list):
    
    cdef Event _next
    cdef bool is_in_callback_list
    cdef EventData data
    cdef bool prevstate
    cdef void *misc, *misc2
    cdef object sens
    
    def __init__(self):
        self.data = EventData()
        
    def __add__(self, f):
        if isinstance(f, Event):
            raise TypeError("Use boolean operations to combine events.")
        elif hasattr(f,'__iter__'):
            if [x for x in f if not hasattr(x,'__call__')]:
                raise TypeError("'%s' object is not callable or a list of callables." % f.__class__.__name__)
            self.extend(f)
        elif hasattr(f,'__call__'):
            self.append(f)
        else:
            raise TypeError("'%s' object is not callable or a list of callables." % f.__class__.__name__)
        return self
        
    def __iadd__(self, f):
        if type(f)==Event:
            self.__add__(f[:])
        return self.__add__(f)
        # TODO: move the code of __add__ to __iadd__ and
        #       make __add__ return a list
        
    #as decorator
    def __call__(self, f):
        self.__add__(f)
        return f
    
    cdef execute(self):
        for f in self:
            f(self.sens)
    
    # return next, removing empty callbacks.
    cdef Event next_non_empty(self):
        cdef Event n
        n = self._next
        while not n and n!=None:
            n.is_in_callback_list = False
            n = self._next = n._next
        return n
        
    # add itself to list, if not already
    cdef Event check_add_to_list(self, Event callback_list):
        if not self.is_in_callback_list:
            self._next = callback_list._next
            callback_list._next = self