Beispiel #1
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);
        }
 /// <summary>
 /// Checks if this patch can skip the transition if it is connected to
 /// StepType.Pass with a upper BranchType.
 /// </summary>
 private static bool CheckPossibleTransitionSkip(Sfc2dEditorControl control, PatchEntity sourcePatch)
 {
     if (sourcePatch.ContainsTransition())
     {
         return(false);
     }
     if (sourcePatch.ContainsRealStep())
     {
         PatchEntity leftPatch = control.Data.SfcEntity.Lookup(sourcePatch.X - 1, sourcePatch.Y);
         if (HasUpperBranchConnection(sourcePatch, leftPatch))
         {
             return(false);
         }
         if (HasLowerBranchConnection(sourcePatch, leftPatch))
         {
             return(false);
         }
         return(FindUpperBranchConnectionsThroughPasses(control, sourcePatch));
     }
     else if (sourcePatch.SfcStepType == StepType.Pass)
     {
         PatchEntity leftPatch = control.Data.SfcEntity.Lookup(sourcePatch.X - 1, sourcePatch.Y);
         return(!HasUpperBranchConnection(sourcePatch, leftPatch));
     }
     return(false);
 }
        private static bool HasLowerBranchConnection(PatchEntity patch, PatchEntity leftPatch)
        {
            bool hasLowerLeftConnection  = leftPatch != null && leftPatch.LowerBranch != BranchType.Unused;
            bool hasLowerRightConnection = patch.LowerBranch != BranchType.Unused;

            return(hasLowerLeftConnection || hasLowerRightConnection);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
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>
 /// The step name must be unique to create step references
 /// </summary>
 private void EnsureUniqueStepKey(PatchEntity data)
 {
     if (_patchNameMap.ContainsKey(data.StepName))
     {
         data.StepName += "?";
         EnsureUniqueStepKey(data);
     }
 }
Beispiel #7
0
        private void AssignActionsFrom(PatchEntity source, IProcessingData context)
        {
            _actions = new Dictionary <ActionQualifier, List <AssignmentExpression> >();
            foreach (ActionQualifier qualifier in (ActionQualifier[])Enum.GetValues(typeof(ActionQualifier)))
            {
                _actions.Add(qualifier, new List <AssignmentExpression>());
            }

            for (int i = 0; i < source.ActionEntries.Count; i++)
            {
                AssignmentExpression expression = ActionMaster.InterpretTransitionText(source.ActionEntries[i].Action, context);
                _actions[source.ActionEntries[i].Qualifier].Add(expression);
            }
        }
        /// <summary>
        /// Looks for left depending steps.
        /// </summary>
        private static void CollectLeftDependingSteps(int currentId, CollectorEntity entity)
        {
            int         leftId   = currentId - (1 << SfcEntity.XKeyShift);
            PatchEntity leftStep = entity.Data.SfcEntity.Lookup(leftId);

            if (leftStep != null)
            {
                if ((entity.UpperBranch && leftStep.UpperBranch == entity.TargetType) ||
                    (!entity.UpperBranch && leftStep.LowerBranch == entity.TargetType))
                {
                    entity.CollectedSteps.Add(leftId);
                    CollectLeftDependingSteps(leftId, entity);
                }
            }
        }
        /// <summary>
        /// Looks for right depending steps.
        /// </summary>
        private static void CollectRightDependingSteps(int currentId, CollectorEntity entity)
        {
            PatchEntity step = entity.Data.SfcEntity.Lookup(currentId);

            if ((entity.UpperBranch && step.UpperBranch == entity.TargetType) ||
                (!entity.UpperBranch && step.LowerBranch == entity.TargetType))
            {
                int rightId = currentId + (1 << SfcEntity.XKeyShift);
                if (entity.Data.SfcEntity.Lookup(rightId) != null)
                {
                    entity.CollectedSteps.Add(rightId);
                    CollectRightDependingSteps(rightId, entity);
                }
            }
        }
        /// <summary>
        /// Checks if this patch can connect to a existing lower patch with:
        /// - Incoming line left/right
        /// - Transition form this patch
        /// </summary>
        private static bool CheckLowerStepConnection(SfcPatchControl control, bool skippedTransition)
        {
            PatchEntity lowerPatch         = control.Master.Data.SfcEntity.Lookup(control.Data.X, control.Data.Y + 1);
            bool        hasLowerActiveStep = lowerPatch != null && lowerPatch.SfcStepType != StepType.Unused;

            if (!hasLowerActiveStep)
            {
                return(false);
            }
            if (skippedTransition || control.Data.ContainsTransition())
            {
                return(true);
            }
            PatchEntity leftPatch = control.Master.Data.SfcEntity.Lookup(control.Data.X - 1, control.Data.Y);

            return(HasLowerBranchConnection(control.Data, leftPatch));
        }
Beispiel #11
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);
        }
Beispiel #12
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);
        }
Beispiel #13
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);
        }
        /// <summary>
        /// Traverses down along passes and tries to find a patch with upper connections but without lower ones.
        /// </summary>
        private static bool FindUpperBranchConnectionsThroughPasses(Sfc2dEditorControl control, PatchEntity currentPatch)
        {
            PatchEntity lowerPatch             = control.Data.SfcEntity.Lookup(currentPatch.X, currentPatch.Y + 1);
            bool        hasLowerTransitionStep = lowerPatch != null && lowerPatch.SfcStepType == StepType.Pass;

            if (!hasLowerTransitionStep)
            {
                return(false);
            }
            PatchEntity leftPatch = control.Data.SfcEntity.Lookup(lowerPatch.X - 1, lowerPatch.Y);

            if (HasUpperBranchConnection(lowerPatch, leftPatch))
            {
                return(true);
            }
            if (HasLowerBranchConnection(lowerPatch, leftPatch))
            {
                return(false);
            }
            return(FindUpperBranchConnectionsThroughPasses(control, lowerPatch));
        }
        /// <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);
        }
Beispiel #16
0
        /// <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
            });
        }
Beispiel #17
0
 public SfcStep(PatchEntity source)
 {
     Id = source.Key;
 }