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)
Example #2
0
 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)