def __init__(self, real_time_mapper=None, register_real_time_data=None, *a, **k): super(CompressorDeviceComponent, self).__init__(*a, **k) self._input_channel_router, self._input_type_router = self.register_disconnectables( [ mixin(CompressorInputRouterMixin, InputChannelRouter)(song=self.song), mixin(CompressorInputRouterMixin, InputTypeRouter)(song=self.song) ]) self._input_router = self.register_disconnectable( InputChannelAndPositionRouter( input_channel_router=self._input_channel_router, input_type_router=self._input_type_router)) self._type_list = self.register_disconnectable( RoutingTypeList(parent_task_group=self._tasks, router=self._input_type_router)) self._channel_list = self.register_disconnectable( RoutingChannelList( parent_task_group=self._tasks, rt_channel_assigner=RoutingMeterRealTimeChannelAssigner( real_time_mapper=real_time_mapper, register_real_time_data=register_real_time_data, parent=self), router=self._input_router)) self._positions_list = self.register_disconnectable( RoutingChannelPositionList( input_channel_router=self._input_router))
def _init_browse_mode(self): self._main_modes.add_mode('browse', [ self._when_track_is_not_frozen( self._enable_stop_mute_solo_as_modifiers, partial(self._view_control.show_view, 'Browser'), self._browser_back_to_top, self._browser_hotswap_mode, self._browser_mode, self._browser_reset_load_memory) ], groups=['add_effect', 'add_track', 'browse'], behaviour=mixin(DynamicBehaviourMixin, CancellableBehaviour) (lambda: not self._browser_hotswap_mode._mode .can_hotswap() and 'add_effect_left')) self._main_modes.add_mode( 'add_effect_right', [ self._when_track_is_not_frozen( self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_right)) ], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect']) self._main_modes.add_mode( 'add_effect_left', [ self._when_track_is_not_frozen( self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_left)) ], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect']) self._main_modes.add_mode( 'add_instrument_track', [ self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_instrument_track) ], behaviour=mixin(ExcludingBehaviourMixin, AlternativeBehaviour)( excluded_groups=['browse', 'add_effect'], alternative_mode='add_default_track'), groups=['add_track']) self._main_modes.add_mode('add_default_track', [ self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_default_track) ], groups=['add_track']) self._main_modes.add_effect_right_button.mode_unselected_color = self._main_modes.add_effect_left_button.mode_unselected_color = self._main_modes.add_instrument_track_button.mode_unselected_color = 'DefaultButton.On'
def auto_arm_restore_behaviour(self, *extra_classes, **extra_params): if not self._auto_arm_restore_behaviour: self._auto_arm_restore_behaviour = mixin( AutoArmRestoreBehaviour, *extra_classes)(auto_arm=self, **extra_params) else: raise not extra_params and not extra_classes or AssertionError return self._auto_arm_restore_behaviour
def create_text_display_line(v_position): display = mixin(CachingControlElement, ConfigurablePhysicalDisplayElement)(v_position=v_position, width_in_chars=DISPLAY_LINE_WIDTH, num_segments=NUM_DISPLAY_LINE_SEGMENTS, name=('Text_Display_{}').format(v_position)) display.set_message_parts(sysex.SET_PROPERTY_MSG_HEADER, ( sysex.SYSEX_END_BYTE,)) for index in xrange(NUM_DISPLAY_LINE_SEGMENTS): display.segment(index).set_position_identifier((index,)) return display
def auto_arm_restore_behaviour(self, *extra_classes, **extra_params): if not self._auto_arm_restore_behaviour: self._auto_arm_restore_behaviour = mixin( AutoArmRestoreBehaviour, *extra_classes)(auto_arm=self, **extra_params) else: pass return self._auto_arm_restore_behaviour
def create_selection_field(h_position, v_position): sysex_identifier = sysex.SET_PROPERTY_MSG_HEADER + ( h_position, sysex.VALUE_PROPERTY_BYTE, v_position) return mixin(CachingControlElement, SysexElement)( sysex_identifier=sysex_identifier, send_message_generator=lambda v: sysex_identifier + (v, sysex.SYSEX_END_BYTE), default_value=0, name=('Selection_Field_{}_{}').format(h_position, v_position))
def create_display_color_element(h_position, v_position, name, **k): sysex_identifier = sysex.SET_PROPERTY_MSG_HEADER + ( h_position, sysex.COLOR_PROPERTY_BYTE, v_position) return mixin(CachingControlElement, ColorSysexElement)( sysex_identifier=sysex_identifier, send_message_generator=(lambda v: sysex_identifier + (v, sysex.SYSEX_END_BYTE)), default_value=0, name=name, **k)
def __init__(self, *a, **k): super(Elements, self).__init__(*a, **k) self.display_up_button = create_button(81, 'Display_Up_Button') self.display_down_button = create_button(82, 'Display_Down_Button') self.up_button = create_button(85, 'Up_Button') self.down_button = create_button(86, 'Down_Button') self.mixer_up_button = create_button(87, 'Mixer_Up_Button') self.mixer_down_button = create_button(88, 'Mixer_Down_Button') self.grid_button = create_button(89, 'Grid_Button') self.options_button = create_button(90, 'Options_Button') self.shift_button = create_button(91, 'Shift_Button', resource_type=PrioritizedResource) self.duplicate_button = create_button(92, 'Duplicate_Button') self.clear_button = create_button(93, 'Clear_Button') self.track_left_button = create_button(102, 'Track_Left_Button') self.track_right_button = create_button(103, 'Track_Right_Button') self.rw_button = create_button(112, 'RW_Button') self.ff_button = create_button(113, 'FF_Button') self.stop_button = create_button(114, 'Stop_Button') self.play_button = create_button(115, 'Play_Button') self.loop_button = create_button(116, 'Loop_Button') self.record_button = create_button(117, 'Record_Button') def with_shift(button): return ComboElement(control=button, modifier=self.shift_button, name=('{}_With_Shift').format(button.name)) self.up_button_with_shift = with_shift(self.up_button) self.down_button_with_shift = with_shift(self.down_button) self.record_button_with_shift = with_shift(self.record_button) self.play_button_with_shift = with_shift(self.play_button) self.track_left_button_with_shift = with_shift(self.track_left_button) self.track_right_button_with_shift = with_shift( self.track_right_button) self.duplicate_button_with_shift = with_shift(self.duplicate_button) pads_raw = [[ create_button(offset + col_index, ('Pad_{}_{}').format(col_index, row_index), msg_type=MIDI_NOTE_TYPE) for col_index in xrange(SESSION_WIDTH) ] for row_index, offset in enumerate((96, 112))] self.pads = ButtonMatrixElement(rows=pads_raw, name='Pads') self.pads_quadratic = ButtonMatrixElement(rows=[ pads_raw[0][4:], pads_raw[1][4:], pads_raw[0][:4], pads_raw[1][:4] ], name='Pads_Quadratic') self.pads_flattened = ButtonMatrixElement( rows=[pads_raw[0] + pads_raw[1]], name='Pads_Flattened') self.shifted_pad_row_1 = ButtonMatrixElement( rows=[[with_shift(control) for control in pads_raw[1]]], name='Pad_Row_1_With_Shift') scene_launch_buttons_raw = [ create_button(83 + row_index, name=('Scene_Launch_Button_{}').format(row_index)) for row_index in xrange(SESSION_HEIGHT) ] self.scene_launch_buttons = ButtonMatrixElement( rows=[scene_launch_buttons_raw], name='Scene_Launch_Buttons') self.shifted_scene_launch_button_1 = with_shift( scene_launch_buttons_raw[1]) sliders = [ SpecialFeedbackChannelSliderElement( MIDI_CC_TYPE, DEFAULT_CHANNEL, 41 + index, name=('Slider_{}').format(index)) for index in xrange(SESSION_WIDTH) ] for slider in sliders: slider.set_feedback_delay(1) self.sliders = ButtonMatrixElement(rows=[sliders], name='Sliders') self.slider_leds = ButtonMatrixElement(rows=[[ create_rgb_led(index + 54, ('Slider_LED_{}').format(index)) for index in xrange(8) ]], name='Slider_LEDs') self.mixer_soft_button_row_0 = ButtonMatrixElement( rows=[[ create_button(identifier, ('Mixer_Soft_Button_{}_0').format(col_index)) for col_index, identifier in enumerate( xrange(59, 59 + SESSION_WIDTH)) ]], name='Mixer_Soft_Button_Row_0') self.mixer_soft_button_row_1 = ButtonMatrixElement( rows=[[ create_button(identifier, ('Mixer_Soft_Button_{}_1').format(col_index)) for col_index, identifier in enumerate( xrange(59 + SESSION_WIDTH, 59 + SESSION_WIDTH * 2)) ]], name='Mixer_Soft_Button_Row_1') self.message_display = SpecialPhysicalDisplayElement( width_in_chars=38, num_segments=NUM_MESSAGE_SEGMENTS, name='Message_Display') self.message_display.set_message_parts(sysex.SHOW_MESSAGE_MSG_HEADER, (sysex.SYSEX_END_BYTE, )) self.center_display_1 = mixin(CachingControlElement, ConfigurablePhysicalDisplayElement)( v_position=0, width_in_chars=9, name='Center_Display_1') self.center_display_2 = mixin(CachingControlElement, ConfigurablePhysicalDisplayElement)( v_position=1, width_in_chars=9, name='Center_Display_2') self.mixer_display_1 = mixin(CachingControlElement, ConfigurablePhysicalDisplayElement)( v_position=2, width_in_chars=9, name='Mixer_Button_Display_1') self.mixer_display_2 = mixin(CachingControlElement, ConfigurablePhysicalDisplayElement)( v_position=3, width_in_chars=9, name='Mixer_Button_Display_2') for display in (self.center_display_1, self.center_display_2, self.mixer_display_1, self.mixer_display_2): display.set_message_parts(sysex.SET_PROPERTY_MSG_HEADER, (sysex.SYSEX_END_BYTE, )) display.segment(0).set_position_identifier((8, )) self.center_color_field = create_display_color_element( 8, 0, 'Center_Color_Field') self.mixer_color_field_1 = create_display_color_element( 8, 1, 'Mixer_Color_Field_1') self.mixer_color_field_2 = create_display_color_element( 8, 2, 'Mixer_Color_Field_2') self.select_buttons_raw = [ create_button(51 + index, ('Select_Button_{}').format(index)) for index in xrange(8) ] self.select_buttons = ButtonMatrixElement( rows=[self.select_buttons_raw], name='Select_Buttons') self.select_buttons_with_shift_raw = [ with_shift(button) for button in self.select_buttons_raw ] self.display_layout_switch = SysexElement( name='Display_Layout_Switch', send_message_generator=lambda v: sysex. SET_SCREEN_LAYOUT_MESSAGE_HEADER + (v, sysex.SYSEX_END_BYTE), default_value=sysex.EMPTY_SCREEN_LAYOUT_BYTE, optimized=True) self.text_display_line_0 = create_text_display_line(0) self.text_display_line_1 = create_text_display_line(1) self.text_display_line_2 = create_text_display_line(2) self.text_display_line_3 = create_text_display_line(3) self.text_display_line_5 = create_text_display_line(5) self.text_display_line_3_with_shift = with_shift( self.text_display_line_3) self.text_display_line_5_with_shift = with_shift( self.text_display_line_5) self.text_display_lines = [ self.text_display_line_0, self.text_display_line_1, self.text_display_line_2, self.text_display_line_3, self.text_display_line_5 ] color_field_line_0_raw, self.color_field_line_0 = create_display_color_element_line( 0) color_field_line_1_raw, _ = create_display_color_element_line(1) self.color_field_line_2_raw, self.color_field_line_2 = create_display_color_element_line( 2) self.color_field_lines_0_1_flattened = ButtonMatrixElement( rows=[color_field_line_0_raw + color_field_line_1_raw], name='Color_Field_Lines_0_1_Flattened') self.color_field_line_2_with_shift = ButtonMatrixElement( rows=[[ with_shift(color_field) for color_field in self.color_field_line_2_raw ]], name='Color_Field_Line_2_With_Shift') selection_field_line_0_raw, _ = create_selection_field_line(0) self.selection_field_line_1_raw, self.selection_field_line_1 = create_selection_field_line( 1) self.selection_field_line_2_raw, self.selection_field_line_2 = create_selection_field_line( 2) self.selection_field_lines_0_1_flattened = ButtonMatrixElement( rows=[ selection_field_line_0_raw + self.selection_field_line_1_raw ], name='Selection_Field_Lines_0_1_Flattened') self.selection_field_line_1_with_shift = ButtonMatrixElement( rows=[[ with_shift(field) for field in self.selection_field_line_1_raw ]], name='Selection_Field_Line_1_With_Shift') self.selection_field_line_2_with_shift = ButtonMatrixElement( rows=[[ with_shift(field) for field in self.selection_field_line_2_raw ]], name='Selection_Field_Line_2_With_Shift') encoders = [ EncoderElement( MIDI_CC_TYPE, DEFAULT_CHANNEL, 21 + index, map_mode=Live.MidiMap.MapMode.relative_smooth_two_compliment, name=('Encoder_{}').format(index)) for index in xrange(8) ] for encoder in encoders: encoder.set_feedback_delay(1) self.encoders = ButtonMatrixElement(rows=[encoders], name='Encoders') self.encoder_color_fields = ButtonMatrixElement( rows=[[ create_display_color_element( index, 1, ('Encoder_Color_Field_{}').format(index)) for index in xrange(8) ]], name='Encoder_Color_Fields')
def footswitch_row_control(*a, **k): c = mixin(FootswitchRowControl, FootswitchControl) return c(FootswitchControl, *a, **k)
def _init_browse_mode(self): self._main_modes.add_mode('browse', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, partial(self._view_control.show_view, 'Browser'), self._browser_back_to_top, self._browser_hotswap_mode, self._browser_mode, self._browser_reset_load_memory)], groups=['add_effect', 'add_track', 'browse'], behaviour=mixin(DynamicBehaviourMixin, CancellableBehaviour)(lambda : not self._browser_hotswap_mode._mode.can_hotswap() and 'add_effect_left')) self._main_modes.add_mode('add_effect_right', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_right))], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect']) self._main_modes.add_mode('add_effect_left', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_left))], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect']) self._main_modes.add_mode('add_instrument_track', [self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_instrument_track)], behaviour=mixin(ExcludingBehaviourMixin, AlternativeBehaviour)(excluded_groups=['browse', 'add_effect'], alternative_mode='add_default_track'), groups=['add_track']) self._main_modes.add_mode('add_default_track', [self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_default_track)], groups=['add_track']) self._main_modes.add_effect_right_button.mode_unselected_color = self._main_modes.add_effect_left_button.mode_unselected_color = self._main_modes.add_instrument_track_button.mode_unselected_color = 'DefaultButton.On'
class Launchpad_X(InstrumentControlMixin, NovationBase): model_family_code = ids.LP_X_FAMILY_CODE element_class = Elements channel_strip_class = ChannelStripComponent session_recording_class = mixin(SessionRecordingMixin, SessionRecordingComponent) track_recording_class = mixin(SessionRecordingMixin, TrackRecordingComponent) target_track_class = ArmedTargetTrackComponent skin = skin def __init__(self, *a, **k): self._last_layout_byte = sysex.SESSION_LAYOUT_BYTE (super(Launchpad_X, self).__init__)(*a, **k) def on_identified(self, midi_bytes): self._elements.firmware_mode_switch.send_value(sysex.DAW_MODE_BYTE) self._elements.layout_switch.send_value(self._last_layout_byte) self._target_track_changed() self._drum_group_changed() self.set_feedback_channels( [DRUM_FEEDBACK_CHANNEL, SCALE_FEEDBACK_CHANNEL]) super(Launchpad_X, self).on_identified(midi_bytes) def _create_components(self): super(Launchpad_X, self)._create_components() self._background = BackgroundComponent(name='Background', add_nop_listeners=True) self._session_layout_mode = partial( self._elements.layout_switch.send_value, sysex.SESSION_LAYOUT_BYTE) self._create_recording_modes() self._create_mixer_modes() self._create_session_modes() self._create_note_modes() self._create_main_modes() self._mixer.set_send_controls = nop self._Launchpad_X__on_layout_switch_value.subject = self._elements.layout_switch def _create_mixer_modes(self): self._mixer_modes = ModesComponent( name='Mixer_Modes', is_enabled=False, enable_skinning=True, layer=Layer( volume_button=(self._elements.scene_launch_buttons_raw[0]), pan_button=(self._elements.scene_launch_buttons_raw[1]), send_a_button=(self._elements.scene_launch_buttons_raw[2]), send_b_button=(self._elements.scene_launch_buttons_raw[3]), stop_button=(self._elements.scene_launch_buttons_raw[4]), mute_button=(self._elements.scene_launch_buttons_raw[5]), solo_button=(self._elements.scene_launch_buttons_raw[6]), arm_button=(self._elements.scene_launch_buttons_raw[7]))) bottom_row = self._elements.clip_launch_matrix.submatrix[:, 7:8] select_none_mode = partial(setattr, self._mixer_modes, 'selected_mode', 'none') self._mixer_modes.add_mode('none', self._session_layout_mode) button_fader_layout_mode = partial( self._elements.layout_switch.send_value, sysex.FADERS_LAYOUT_BYTE) def add_fader_mode(name, color, is_pan=False): control_dict = {'{}_controls'.format(name): 'button_faders'} if is_pan: control_dict[ 'track_color_controls'] = 'button_fader_color_elements' else: control_dict[ 'static_color_controls'] = 'button_fader_color_elements' self._mixer_modes.add_mode( name, (partial( self._elements.button_fader_setup_element.send_value, sysex.FADER_HORIZONTAL_ORIENTATION if is_pan else sysex.FADER_VERTICAL_ORIENTATION, sysex.FADER_BIPOLAR if is_pan else sysex.FADER_UNIPOLAR), partial(self._mixer.set_static_color_value, color), self._clear_send_cache_of_button_fader_color_elements, AddLayerMode(self._mixer, Layer(**control_dict)), button_fader_layout_mode), behaviour=ReenterBehaviour(on_reenter=select_none_mode)) add_fader_mode('volume', Rgb.GREEN.midi_value) add_fader_mode('pan', 0, True) add_fader_mode('send_a', Rgb.VIOLET.midi_value) add_fader_mode('send_b', Rgb.DARK_BLUE.midi_value) self._mixer_modes.add_mode( 'stop', (self._session_layout_mode, AddLayerMode(self._session, Layer(stop_track_clip_buttons=bottom_row))), behaviour=ReenterBehaviour(on_reenter=select_none_mode)) self._mixer_modes.add_mode( 'mute', (self._session_layout_mode, AddLayerMode(self._mixer, Layer(mute_buttons=bottom_row))), behaviour=ReenterBehaviour(on_reenter=select_none_mode)) self._mixer_modes.add_mode( 'solo', (self._session_layout_mode, AddLayerMode(self._mixer, Layer(solo_buttons=bottom_row))), behaviour=ReenterBehaviour(on_reenter=select_none_mode)) self._mixer_modes.add_mode( 'arm', (self._session_layout_mode, AddLayerMode(self._mixer, Layer(arm_buttons=bottom_row))), behaviour=ReenterBehaviour(on_reenter=select_none_mode)) self._mixer_modes.selected_mode = 'none' def _clear_send_cache_of_button_fader_color_elements(self): for element in self._elements.button_fader_color_elements_raw: element.clear_send_cache() def _create_session_modes(self): self._session_overview = SessionOverviewComponent( name='Session_Overview', is_enabled=False, session_ring=(self._session_ring), enable_skinning=True, layer=Layer(button_matrix='clip_launch_matrix')) self._session_modes = SessionModesComponent( name='Session_Modes', is_enabled=False, layer=Layer( cycle_mode_button='session_mode_button', mode_button_color_control='session_button_color_element')) self._session_modes.add_mode( 'launch', AddLayerMode(self._session, Layer(scene_launch_buttons='scene_launch_buttons'))) self._session_modes.add_mode( 'mixer', DelayMode(self._mixer_modes, SESSION_MODES_SWITCH_DELAY)) (self._session_modes.add_mode( 'overview', (self._session_layout_mode, self._session_overview, AddLayerMode( self._session_navigation, Layer(page_up_button='up_button', page_down_button='down_button', page_left_button='left_button', page_right_button='right_button')), AddLayerMode( self._background, Layer(scene_launch_buttons='scene_launch_buttons')))), ) self._session_modes.selected_mode = 'launch' def _create_note_modes(self): self._drum_group = DrumGroupComponent( name='Drum_Group', is_enabled=False, translation_channel=DRUM_FEEDBACK_CHANNEL, layer=Layer(matrix='drum_pads', scroll_up_button='left_button', scroll_down_button='right_button', scroll_page_up_button='up_button', scroll_page_down_button='down_button')) self._scale_pad_translator = ConfigurablePlayableComponent( SCALE_FEEDBACK_CHANNEL, name='Scale_Pads', is_enabled=False, layer=Layer(matrix='scale_pads')) self._note_modes = ModesComponent(name='Note_Modes', is_enabled=False) self._note_modes.add_mode( 'scale', (self._scale_pad_translator, AddLayerMode((self._background), layer=Layer(up_button='up_button', down_button='down_button', left_button='left_button', right_button='right_button')))) self._note_modes.add_mode('drum', self._drum_group) self._note_modes.selected_mode = 'scale' self._Launchpad_X__on_note_mode_changed.subject = self._note_modes def _create_main_modes(self): self._main_modes = ModesComponent( name='Main_Modes', is_enabled=False, layer=Layer(session_button='session_mode_button', note_button='note_mode_button', custom_button='custom_mode_button')) self._main_modes.add_mode('session', (self._session_modes), behaviour=(ImmediateBehaviour())) self._main_modes.add_mode('note', (self._note_modes), behaviour=(ImmediateBehaviour())) self._main_modes.add_mode('custom', None, behaviour=(ImmediateBehaviour())) self._main_modes.selected_mode = 'session' self._main_modes.set_enabled(True) self._Launchpad_X__on_main_mode_changed.subject = self._main_modes @listens('selected_mode') def __on_main_mode_changed(self, mode): self._recording_modes.selected_mode = 'track' if mode == 'note' else 'session' if mode == 'session': self._session_modes.revert_to_main_mode() self._update_controlled_track() self._elements.layout_switch.enquire_value() @listens('selected_mode') def __on_note_mode_changed(self, mode): if self._note_modes.is_enabled(): self._update_controlled_track() @listens('value') def __on_layout_switch_value(self, value): self._last_layout_byte = value def _drum_group_changed(self): drum_group = self._drum_group_finder.drum_group drum_groud_valid = liveobj_valid(drum_group) self._drum_group.set_drum_group_device(drum_group) self._elements.note_layout_switch.send_value( sysex.DRUM_LAYOUT_BYTE if drum_groud_valid else sysex. SCALE_LAYOUT_BYTE) self._note_modes.selected_mode = 'drum' if drum_groud_valid else 'scale' def _is_instrument_mode(self): return self._main_modes.selected_mode == 'note' def _feedback_velocity_changed(self, feedback_velocity): self._elements.scale_feedback_switch.send_value(feedback_velocity)
def auto_arm_restore_behaviour(self, *extra_classes, **extra_params): if not self._auto_arm_restore_behaviour: self._auto_arm_restore_behaviour = mixin(AutoArmRestoreBehaviour, *extra_classes)(auto_arm=self, **extra_params) else: raise not extra_params and not extra_classes or AssertionError return self._auto_arm_restore_behaviour