/// <summary> /// Collects all alternative branches from this step. /// If it returns only one transition is not an alternative branch but a normal transition. /// </summary> private static List <SfcTransition> CollectUpperAlternativeBranches(SfcStep source, int patchId, ProgrammableLogicController pu) { List <SfcTransition> transitions = new List <SfcTransition>(); List <int> collected = Collector.CollectHorizontal(patchId, pu.SfcProgramData, BranchType.Single, true); foreach (int step in collected) { if (pu.SfcProgramData.SfcEntity.Lookup(step).ContainsTransition()) { SfcTransition transition = CreateTransition(step, pu); transition.DependingSteps.Add(source); transitions.Add(transition); } else { int lowerStepId = step + 1; PatchEntity lowerEntry = pu.SfcProgramData.SfcEntity.Lookup(lowerStepId); if (lowerEntry != null && lowerEntry.SfcStepType == StepType.Pass) { transitions.AddRange(CollectUpperAlternativeBranches(source, lowerStepId, pu)); } } } return(transitions); }
/// <summary> /// Creates a new SfcTransition with the given transitionPatchId /// </summary> private static SfcTransition CreateTransition(int transitionPatchId, ProgrammableLogicController pu) { string transitionText = pu.SfcProgramData.SfcEntity.Lookup(transitionPatchId).TransitionText; BooleanExpression expression = TransitionMaster.InterpretTransitionText(transitionText, pu); SfcTransition transition = new SfcTransition(expression, transitionPatchId); return(transition); }
/// <summary> /// Assigns all destinations to this transition /// </summary> public static void AssignTransitionDestinations(SfcTransition transition, SfcProgramData data) { List <SfcStep> lowerTargets = CollectLowerSimultaneousBranches(transition.Id, data); if (lowerTargets == null || lowerTargets.Count > 0) { transition.NextSteps = lowerTargets; } else { SfcStep alternativeStep = FindAlternativeMergeTarget(transition.Id, data); List <SfcStep> alternativeList = new List <SfcStep>(1); if (alternativeStep != null) { alternativeList.Add(alternativeStep); } transition.NextSteps = alternativeList; } }
/// <summary> /// Collects all Simultaneous branches to merge from this step. /// null if there is none. /// </summary> private static List <SfcTransition> CollectUpperSimultaneousMerge(int sourceId, ProgrammableLogicController pu) { List <int> collected = Collector.CollectHorizontal(sourceId, pu.SfcProgramData, BranchType.Double, true); if (collected.Count <= 1) { PatchEntity currentPatch = pu.SfcProgramData.SfcEntity.Lookup(sourceId); int lowerId = sourceId + 1; PatchEntity lowerPatch = pu.SfcProgramData.SfcEntity.Lookup(lowerId); if (!currentPatch.ContainsTransition() && lowerPatch != null && lowerPatch.SfcStepType == StepType.Pass) { return(CollectUpperSimultaneousMerge(lowerId, pu)); } return(null); } PatchEntity transitionPatch = FindSimultaneousTransition(collected, pu.SfcProgramData); List <SfcStep> connectedSteps = CollectConnectedSteps(collected, pu.SfcProgramData); SfcTransition transition = CreateTransition(transitionPatch.Key, pu); transition.DependingSteps = connectedSteps; return(new List <SfcTransition> { transition }); }