def send( self, event_type, ctrl_id, value ):
     '''the signature of this function follows event_loop.event_receiver'''
     log.debug("Emmiting {} {} {}".format(event_type, ctrl_id, value))
     i= ctrl_id
     if event_type==EVENT_BUTTON:
         
         self.device.emit( (uinput.BTN_0[0], uinput.BTN_0[1]+i), value )
     if event_type==EVENT_AXIS:
         self.device.emit( (uinput.ABS_X[0], uinput.ABS_X[1]+i), value )
def event_loop( joystick_file, event_receiver ):
    '''event loop that reads events from the physical joystick.
    joystick_file is a actual file (object), not a file path.'''
    while True:
        data= joystick_file.read(8)
        d1,time,ignore1,ignore2,d2,d3,event_type,ctrl_id= data
        axis_value= d3
        button_value= ord(d2)
        event_type= ord(event_type)
        ctrl_id= ord(ctrl_id)
        axis_value= struct.unpack('b', axis_value)[0]
        if not event_type in (EVENT_AXIS, EVENT_BUTTON):
            continue #event_type contains some strange stuff on the beggining of file
        value= axis_value if event_type==EVENT_AXIS else button_value
        log.debug("joystick received {} {} {}".format(event_type, ctrl_id, value))
        event_receiver( event_type, ctrl_id, value)
    def execute(self, p, locked):
        """p: das Feld auf dem die Aktion ausgeführt werden soll
        locked: eine Menge von Positionen die nicht bewegt werden dürfen. 
        Die erste Position die durch die Aktion betreten wird, wird autoamtisch gelockt"""
        log.debug("executing PosAction; start: {}, actions: {}".format(self.start_position,
                                                                       self.actions))
        l = locked.copy()
        l.add(self.locked_position()) # die erste Position wird automatisch gelockt!
        path = a_star(p.shape[0],
                      puz.empty_position(p),
                      self.start_position, l)
        assert path, "PosAction not executable, starting position not reachable"
        init_actions = coords_to_actions(path)
#        log.info("moving into start pos., path: {}".format(init_actions))
        p = puz.apply_actions(p, init_actions)
        p = puz.apply_actions(p, self.actions)
        return p, init_actions + self.actions