Rules can be set to run only if the action matches a given pattern.
§1. Many rules are predicated on action patterns: "Instead of opening a closed door", say, is a rule in the "instead of opening" rulebook which is predicated on the action applying to "a closed door". This is stored in the following actions-feature corner of the Runtime Context Data (in assertions) for the rule.
typedef struct actions_rcd_data { int always_test_actor; ...even if no AP was given, test that actor is player? int never_test_actor; ...for instance, for a parametrised rather than action rulebook int marked_for_anyone; any actor is allowed to perform this action CLASS_DEFINITION } actions_rcd_data; actions_rcd_data *ActionRules::new_rcd_data(id_runtime_context_data *idrcd) { actions_rcd_data *ard = CREATE(actions_rcd_data); ard->always_test_actor = FALSE; ard->never_test_actor = FALSE; ard->marked_for_anyone = FALSE; return ard; }
- The structure actions_rcd_data is private to this section.
§2. Note that if the actions feature is inactive, then this never runs...
int ActionRules::new_rcd(id_runtime_context_data *idrcd) { CREATE_RCD_FEATURE_DATA(actions, idrcd, ActionRules::new_rcd_data) return FALSE; }
§3. ...with the result that arcd is always null in the function below.
void ActionRules::set_always_test_actor(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) arcd->always_test_actor = TRUE; } int ActionRules::get_always_test_actor(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) return arcd->always_test_actor; return FALSE; } void ActionRules::clear_always_test_actor(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) arcd->always_test_actor = FALSE; } void ActionRules::set_never_test_actor(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) arcd->never_test_actor = TRUE; } int ActionRules::get_never_test_actor(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) return arcd->never_test_actor; return TRUE; } void ActionRules::set_marked_for_anyone(id_runtime_context_data *idrcd, int to) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) arcd->marked_for_anyone = to; } int ActionRules::get_marked_for_anyone(id_runtime_context_data *idrcd) { actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) return arcd->marked_for_anyone; return FALSE; }
§4. The following all make use the action pattern idrcd->ap in the RCD. This seems a little odd: why isn't it in the actions_rcd_data? The answer is that it needs to exist even when the actions feature is inactive, because it's still used for parsing predicates for non-action-based rulebooks.
void ActionRules::set_ap(id_runtime_context_data *idrcd, action_pattern *ap) { if (idrcd) idrcd->ap = ap; } action_pattern *ActionRules::get_ap(id_runtime_context_data *idrcd) { if (idrcd) return idrcd->ap; return NULL; } int ActionRules::within_action_context(id_runtime_context_data *idrcd, action_name *an) { if (idrcd == NULL) return FALSE; actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if (arcd) return ActionPatterns::covers_action(idrcd->ap, an); return FALSE; } action_name *ActionRules::required_action(id_runtime_context_data *idrcd) { if (idrcd == NULL) return FALSE; actions_rcd_data *arcd = RCD_FEATURE_DATA(actions, idrcd); if ((arcd) && (idrcd->ap)) return ActionPatterns::single_positive_action(idrcd->ap); return NULL; } action_name *ActionRules::required_action_for_booking(booking *br) { imperative_defn *id = Rules::get_imperative_definition(br->rule_being_booked); if (id) return ActionRules::required_action(&(id->body_of_defn->runtime_context_data)); return NULL; } void ActionRules::suppress_action_testing(id_runtime_context_data *idrcd) { if (idrcd->ap) ActionPatterns::suppress_action_testing(idrcd->ap); }