示例#1
0
        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);
 }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /// <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);
        }
示例#11
0
        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);
        }