예제 #1
0
    def process_switch_obj(self, obj: Switch, state, logical):
        """Process a new switch state change for a switch by name.

        Args:
            obj: The switch object.
            state: Boolean or int of state of the switch you're processing,
                True/1 is active, False/0 is inactive.
            logical: Boolean which specifies whether the 'state' argument
                represents the "physical" or "logical" state of the switch. If
                True, a 1 means this switch is active and a 0 means it's
                inactive, regardless of the NC/NO configuration of the switch.
                If False, then the state parameter passed will be inverted if
                the switch is configured to be an 'NC' type. Typically the
                hardware will send switch states in their raw (logical=False)
                states, but other interfaces like the keyboard and OSC will use
                logical=True.

        This is the method that is called by the platform driver whenever a
        switch changes state. It's also used by the "other" modules that
        activate switches, including the keyboard and OSC interfaces.

        State 0 means the switch changed from active to inactive, and 1 means
        it changed from inactive to active. (The hardware & platform code
        handles NC versus NO switches and translates them to 'active' versus
        'inactive'.)
        """
        # We need int, but this lets it come in as boolean also
        if state:
            state = 1
        else:
            state = 0

        # flip the logical & physical states for NC switches
        hw_state = state

        if obj.invert:
            if logical:  # NC + logical means hw_state is opposite of state
                hw_state ^= 1
            else:
                # NC w/o logical (i.e. hardware state was sent) means logical
                # state is the opposite
                state ^= 1

        # Update the hardware state since we always want this to match real hw
        obj.hw_state = hw_state

        # if the switch is active, check to see if it's recycle_time has passed
        if state and not self._check_recycle_time(obj, state):
            self.machine.clock.schedule_once(
                partial(self._recycle_passed, obj, state, logical,
                        obj.hw_state),
                timeout=obj.recycle_clear_time - self.machine.clock.get_time())
            return

        obj.state = state  # update the switch device

        if state:
            # update the switch's next recycle clear time
            obj.recycle_clear_time = (self.machine.clock.get_time() +
                                      obj.recycle_secs)

        # if the switch is already in this state, then abort
        if self.switches[obj.name].state == state:

            if not obj.recycle_secs:
                self.warning_log(
                    "Received duplicate switch state, which means this switch "
                    "had some non-debounced state changes. This could be "
                    "nothing, but if it happens a lot it could indicate noise "
                    "or interference on the line. Switch: %s", obj.name)
            return

        if state:
            self.info_log("<<<<<<< '{}' active >>>>>>>".format(obj.name))
        else:
            self.info_log("<<<<<<< '{}' inactive >>>>>>>".format(obj.name))

        # Update the switch controller's logical state for this switch
        self.set_state(obj.name, state)

        self._call_handlers(obj.name, state)

        self._cancel_timed_handlers(obj.name, state)

        for monitor in self.monitors:
            monitor(
                MonitoredSwitchChange(name=obj.name,
                                      label=obj.label,
                                      platform=obj.platform,
                                      num=obj.hw_switch.number,
                                      state=state))
예제 #2
0
    def process_switch_obj(self, obj: Switch, state, logical):
        """Process a new switch state change for a switch by name.

        Args:
            obj: The switch object.
            state: Boolean or int of state of the switch you're processing,
                True/1 is active, False/0 is inactive.
            logical: Boolean which specifies whether the 'state' argument
                represents the "physical" or "logical" state of the switch. If
                True, a 1 means this switch is active and a 0 means it's
                inactive, regardless of the NC/NO configuration of the switch.
                If False, then the state parameter passed will be inverted if
                the switch is configured to be an 'NC' type. Typically the
                hardware will send switch states in their raw (logical=False)
                states, but other interfaces like the keyboard and OSC will use
                logical=True.

        This is the method that is called by the platform driver whenever a
        switch changes state. It's also used by the "other" modules that
        activate switches, including the keyboard and OSC interfaces.

        State 0 means the switch changed from active to inactive, and 1 means
        it changed from inactive to active. (The hardware & platform code
        handles NC versus NO switches and translates them to 'active' versus
        'inactive'.)
        """
        # We need int, but this lets it come in as boolean also
        if state:
            state = 1
        else:
            state = 0

        # flip the logical & physical states for NC switches
        hw_state = state

        if obj.invert:
            if logical:  # NC + logical means hw_state is opposite of state
                hw_state ^= 1
            else:
                # NC w/o logical (i.e. hardware state was sent) means logical
                # state is the opposite
                state ^= 1

        # if the switch is already in this state, then abort
        if obj.state == state:
            if not self.machine.options['production']:
                self.warning_log(
                    "Received duplicate switch state %s for switch %s from the platform interface.",
                    state,
                    obj.name,
                    error_no=1)
            return

        # Update the hardware state since we always want this to match real hw
        obj.hw_state = hw_state
        # update the switch device
        obj.state = state
        obj.last_change = self.machine.clock.get_time()

        if state:
            self.info_log("<<<<<<< '%s' active >>>>>>>", obj.name)
        else:
            self.info_log("<<<<<<< '%s' inactive >>>>>>>", obj.name)

        self._call_handlers(obj, state)

        self._cancel_timed_handlers(obj.name, state)

        for monitor in self.monitors:
            monitor(
                MonitoredSwitchChange(name=obj.name,
                                      label=obj.label,
                                      platform=obj.platform,
                                      num=obj.hw_switch.number,
                                      state=state))