public ComputeChanges ( bool apply, Runner runner ) : bool | ||
apply | bool | Indicates that the changes should be applied directly |
runner | Runner | |
Résultat | bool |
/// <summary> /// Computes the changes related to this event /// </summary> /// <param name="apply">Indicates that the changes should be applied directly</param> /// <param name="runner"></param> public override bool ComputeChanges(bool apply, Runner runner) { bool retVal = base.ComputeChanges(apply, runner); if (retVal) { // Computes the list of variable updates Updates = new List <VariableUpdate>(); foreach (Action action in SubStep.Actions) { if (action.Statement != null) { VariableUpdate update = new VariableUpdate(action, SubStep.Dictionary, null); update.ComputeChanges(false, runner); Updates.Add(update); } else { action.AddError("Cannot parse action statement"); } } // TODO : Determine if we want to do this // runner.HandleEnterAndLeaveStateActions(null, Updates); runner.CheckUpdatesCompatibility(Updates); } return(retVal); }
/// <summary> /// Applies the selected actions and update the system state /// </summary> /// <param name="activations"></param> /// <param name="updates"></param> /// <param name="priority"></param> public void EvaluateActivations(HashSet<Activation> activations, acceptor.RulePriority priority, ref List<VariableUpdate> updates) { Dictionary<IVariable, Change> changes = new Dictionary<IVariable, Change>(); Dictionary<Change, VariableUpdate> traceBack = new Dictionary<Change, VariableUpdate>(); foreach (Activation activation in activations) { if (activation.RuleCondition.Actions.Count > 0) { // Register the fact that a rule has been triggered RuleFired ruleFired = new RuleFired(activation, priority); EventTimeLine.AddModelEvent(ruleFired, this, true); ExplanationPart changesExplanation = ExplanationPart.CreateSubExplanation(activation.Explanation, "Changes"); // Registers all model updates due to this rule triggering foreach (Action action in activation.RuleCondition.Actions) { if (action.Statement != null) { VariableUpdate variableUpdate = new VariableUpdate(action, activation.Instance, priority); variableUpdate.ComputeChanges(false, this); EventTimeLine.AddModelEvent(variableUpdate, this, false); ruleFired.AddVariableUpdate(variableUpdate); if (changesExplanation != null) { changesExplanation.SubExplanations.Add(variableUpdate.Explanation); } updates.Add(variableUpdate); if (CheckForCompatibleChanges) { ChangeList actionChanges = variableUpdate.Changes; if (variableUpdate.Action.Statement is ProcedureCallStatement) { Dictionary<IVariable, Change> procedureChanges = new Dictionary<IVariable, Change>(); foreach (Change change in variableUpdate.Changes.Changes) { procedureChanges[change.Variable] = change; } actionChanges = new ChangeList(); foreach (Change change in procedureChanges.Values) { actionChanges.Add(change, false, this); } } foreach (Change change in actionChanges.Changes) { IVariable variable = change.Variable; if (changes.ContainsKey(change.Variable)) { Change otherChange = changes[change.Variable]; Action otherAction = traceBack[otherChange].Action; if (!variable.Type.CompareForEquality(otherChange.NewValue, change.NewValue)) { string action1 = ((INamable) action.Enclosing).FullName + " : " + variableUpdate.Action.FullName; string action2 = ((INamable) otherAction.Enclosing).FullName + " : " + traceBack[otherChange].Action.FullName; variableUpdate.Action.AddError( "Simultaneous change of the variable " + variable.FullName + " with different values. Conflit between\n" + action1 + "\n and \n" + action2); } } else { changes.Add(change.Variable, change); traceBack.Add(change, variableUpdate); } } } } else { action.AddError("Cannot parse action statement"); } } } } // Handles the leave & enter state rules List<VariableUpdate> updatesToProcess = updates; updates = new List<VariableUpdate>(); // Avoid considering twice the same transition List<Tuple<State, State>> transitions = new List<Tuple<State, State>>(); while (updatesToProcess.Count > 0) { List<VariableUpdate> newUpdates = new List<VariableUpdate>(); foreach (VariableUpdate update in updatesToProcess) { updates.Add(update); foreach (Change change in update.Changes.Changes) { if (change.Variable.Type is StateMachine) { State leavingState = (State) change.PreviousValue; State enteringState = (State) change.NewValue; bool transitionFound = false; foreach (Tuple<State, State> transition in transitions) { if ((transition.Item1 == leavingState) && (transition.Item2 == enteringState)) { transitionFound = true; break; } } if (! transitionFound) { Tuple<State, State> transition = new Tuple<State, State>(leavingState, enteringState); transitions.Add(transition); HandleLeaveState(priority, newUpdates, change.Variable, leavingState, enteringState); HandleEnterState(priority, newUpdates, change.Variable, leavingState, enteringState); } } } } updatesToProcess = newUpdates; } }