private static SfcStep CheckAlternative(PatchEntity lowerStep, SfcProgramData data) { switch (lowerStep.SfcStepType) { case StepType.StartingStep: case StepType.Step: return(data.ControlMap[lowerStep.Key]); case StepType.Jump: int reference = data.StepMaster.GetNameKey(lowerStep.StepName); return(data.ControlMap[reference]); case StepType.Pass: SfcStep foundStep = FindAlternativeMergeTarget(lowerStep.Key, data); if (foundStep != null) { return(foundStep); } break; case StepType.Unused: break; } return(null); }
/// <summary> /// Creates a new collextor entity to hold the data /// </summary> /// <param name="data">program reference</param> /// <param name="targetType">which branch type to search</param> /// <param name="upperBranch">true for upper, false for lower</param> public CollectorEntity(SfcProgramData data, BranchType targetType, bool upperBranch) { Data = data; CollectedSteps = new List <int>(); TargetType = targetType; UpperBranch = upperBranch; }
/// <summary> /// Collects all steps horizontally connected with the given targetType from sourceId /// </summary> public static List <int> CollectHorizontal(int sourceId, SfcProgramData data, BranchType targetType, bool upperBranch) { CollectorEntity entity = new CollectorEntity(data, targetType, upperBranch); entity.CollectedSteps.Add(sourceId); CollectLeftDependingSteps(sourceId, entity); CollectRightDependingSteps(sourceId, entity); return(entity.CollectedSteps); }
/// <summary> /// Looks for an connection from this patch to any upper connected step (including itself). /// </summary> public static SfcStep FindUpperConnectedStep(int id, SfcProgramData data) { if (data.SfcEntity.Lookup(id).ContainsRealStep()) { return(data.ControlMap[id]); } else if (data.SfcEntity.Lookup(id).SfcStepType == StepType.Pass) { int upperId = id - 1; if (data.SfcEntity.Lookup(upperId) != null) { return(FindUpperConnectedStep(upperId, data)); } } return(null); }
private static PatchEntity FindSimultaneousTransition(List <int> patches, SfcProgramData data) { PatchEntity transitionPatch = null; foreach (int step in patches) { transitionPatch = data.SfcEntity.Lookup(step); if (transitionPatch != null && transitionPatch.ContainsTransition()) { break; } } if (transitionPatch == null) { Godot.GD.PushError("It is not allowed wo have Simultaneous branches without one transition!"); } return(transitionPatch); }
private static List <SfcStep> CollectConnectedSteps(List <int> patches, SfcProgramData data) { List <SfcStep> connectedSteps = new List <SfcStep>(); foreach (int step in patches) { SfcStep connectedStep = Collector.FindUpperConnectedStep(step, data); if (connectedStep != null) { connectedSteps.Add(connectedStep); } } if (connectedSteps.Count < 2) { Godot.GD.PushError("It does not make sense to merge one branch."); } return(connectedSteps); }
private static SfcStep FindAlternativeMergeTarget(int holder, SfcProgramData data) { List <int> collected = Collector.CollectHorizontal(holder, data, BranchType.Single, false); foreach (int step in collected) { int subId = step + 1; PatchEntity lowerStep = data.SfcEntity.Lookup(subId); if (lowerStep != null) { SfcStep target = CheckAlternative(lowerStep, data); if (target != null) { return(target); } } } return(null); }
/// <summary> /// Collects the list of lower simultaneous branches if possible. /// Null if there is an error in the diagram /// </summary> private static List <SfcStep> CollectLowerSimultaneousBranches(int holder, SfcProgramData data) { List <int> collected = Collector.CollectHorizontal(holder, data, BranchType.Double, false); List <SfcStep> targetSteps = new List <SfcStep>(); foreach (int step in collected) { int subId = step + 1; PatchEntity lowerStep = data.SfcEntity.Lookup(subId); if (lowerStep != null) { if (!FillSimultaneous(lowerStep, targetSteps, data)) { return(null); } } } return(targetSteps); }
/// <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> /// Looks for a connected lower step from this patch /// </summary> public static SfcStep FindLowerConnectedStep(int id, SfcProgramData data) { int subId = id + 1; PatchEntity lowerStep = data.SfcEntity.Lookup(subId); if (lowerStep != null) { if (data.SfcEntity.Lookup(lowerStep.Key).ContainsRealStep()) { return(data.ControlMap[lowerStep.Key]); } else if (lowerStep.SfcStepType == StepType.Pass) { return(FindLowerConnectedStep(lowerStep.Key, data)); } else if (lowerStep.SfcStepType == StepType.Jump) { int reference = data.StepMaster.GetNameKey(lowerStep.StepName); return(data.ControlMap[reference]); } } return(null); }
private static bool FillSimultaneous(PatchEntity lowerStep, List <SfcStep> targetSteps, SfcProgramData data) { switch (lowerStep.SfcStepType) { case StepType.StartingStep: case StepType.Step: targetSteps.Add(data.ControlMap[lowerStep.Key]); break; case StepType.Jump: if (data.StepMaster.ContainsStep(lowerStep.StepName)) { int reference = data.StepMaster.GetNameKey(lowerStep.StepName); targetSteps.Add(data.ControlMap[reference]); } else { return(false); } break; case StepType.Pass: SfcStep foundStep = Collector.FindLowerConnectedStep(lowerStep.Key, data); if (foundStep != null) { targetSteps.Add(foundStep); } break; case StepType.Unused: break; } return(true); }