def test_mixer_interaction( sim_info: SimInfo, mixer_interaction_id: int, target: Any=None, interaction_context: InteractionContext=None, **kwargs ) -> TestResult: """test_mixer_interaction(\ sim_info,\ mixer_interaction_id,\ target=None,\ interaction_context=None,\ **kwargs\ ) Test to see if a Mixer Interaction can be pushed into the Queue of a Sim. :param sim_info: An instance of a Sim. :type sim_info: SimInfo :param mixer_interaction_id: The decimal identifier of a mixer interaction. :type mixer_interaction_id: int :param target: The target of the interaction. Default is None. :type target: Any, optional :param interaction_context: The context to queue the interaction with. See also :func:`~create_interaction_context`. Default is None. :type interaction_context: InteractionContext, optional :return: The result of testing a push of the interaction to the queue of a Sim. :rtype: TestResult """ from autonomy.content_sets import get_valid_aops_gen sim = CommonSimUtils.get_sim_instance(sim_info) if sim is None: return TestResult.NONE if sim.posture is None: return TestResult.NONE if target is not None and CommonTypeUtils.is_sim_or_sim_info(target): target = CommonSimUtils.get_sim_instance(target) mixer_interaction_instance = CommonInteractionUtils._load_interaction_instance(mixer_interaction_id) if mixer_interaction_instance is None: return TestResult.NONE source_interaction = sim.posture.source_interaction if source_interaction is None: return TestResult.NONE if hasattr(mixer_interaction_instance, 'lock_out_time') and mixer_interaction_instance.lock_out_time: sim_specific_lockout = mixer_interaction_instance.lock_out_time.target_based_lock_out else: sim_specific_lockout = False if sim_specific_lockout and sim.is_sub_action_locked_out(mixer_interaction_instance): return TestResult.NONE super_interaction_instance = source_interaction.super_affordance interaction_context = interaction_context or CommonSimInteractionUtils.create_interaction_context(sim_info) for (aop, test_result) in get_valid_aops_gen( target, mixer_interaction_instance, super_interaction_instance, source_interaction, interaction_context, False, push_super_on_prepare=False ): test_result: TestResult = test_result if test_result is None or test_result.result: continue interaction_constraint = aop.constraint_intersection(sim=sim, posture_state=None) # noinspection PyPropertyAccess posture_constraint = sim.posture_state.posture_constraint_strict constraint_intersection = interaction_constraint.intersect(posture_constraint) if not constraint_intersection.valid: continue return aop.test(interaction_context, **kwargs)
def __call__(self, sim, resolver, insert_strategy=QueueInsertStrategy.NEXT, must_run_next=False, **kwargs): if self.super_affordance_override is not None: push_super_on_prepare = True source_interaction = None source_affordance = self.super_affordance_override for super_interaction in sim.running_interactions_gen( self.super_affordance_override): source_interaction = super_interaction push_super_on_prepare = False break else: push_super_on_prepare = False source_interaction = sim.posture.source_interaction if source_interaction is None: logger.error( '{} in posture {} does not have a source interaction', sim, sim.posture) return TestResult( False, '{} in posture {} does not have a source interaction', sim, sim.posture) source_affordance = source_interaction.super_affordance for social_group in sim.get_groups_for_sim_gen(): if social_group.disallow_reaction_mixers: return TestResult( False, 'Could not push reaction mixer {} on {}. Disallowed by social group {}', self.affordance, sim, social_group) sim_specific_lockout = self.affordance.lock_out_time.target_based_lock_out if self.affordance.lock_out_time is not None else False if sim_specific_lockout and sim.is_sub_action_locked_out( self.affordance): return TestResult( False, 'Reaction Mixer Affordance {} is currently locked out.', self.affordance) if self.affordance_target is not None: targets = [ target.get_sim_instance() if target.is_sim else target for target in resolver.get_participants(self.affordance_target) if target is not None ] else: targets = [None] if source_interaction is not None: potential_targets = source_interaction.get_potential_mixer_targets( ) targets.extend( self.affordance.filter_mixer_targets( source_interaction, potential_targets, sim)) context = InteractionContext(sim, InteractionSource.REACTION, Priority.High, insert_strategy=insert_strategy, must_run_next=must_run_next) for target in targets: for (aop, test_result) in get_valid_aops_gen( target, self.affordance, source_affordance, source_interaction, context, False, push_super_on_prepare=push_super_on_prepare, aop_kwargs=kwargs): if not test_result: continue interaction_constraint = aop.constraint_intersection( sim=sim, posture_state=None) posture_constraint = sim.posture_state.posture_constraint_strict constraint_intersection = interaction_constraint.intersect( posture_constraint) if constraint_intersection.valid: mixer_result = aop.execute(context) if not mixer_result: continue if sim.queue.always_start_inertial: running_interaction = sim.queue.running if running_interaction is not None and not running_interaction.is_super: running_interaction.cancel( FinishingType.DISPLACED, cancel_reason_msg='Reaction displaced mixer.') return mixer_result return TestResult( False, "Could not push reaction affordance {} on {}. It's likely that the Sim is in a posture that is incompatible with this mixer.", self.affordance, sim)