Пример #1
0
 // copy all data from template except transition because its a reference of PetriNet (just init overridedName)
 internal void import(TransitionLink template)
 {
     this.links = new List <Link>();
     foreach (Link l in template.links)
     {
         this.links.Add(new Link(l));
     }
     this.transition.overridedLabel = template.transition.overridedLabel;
     this.isSystemAction            = template.isSystemAction;
     this.isEndAction = template.isEndAction;
     this.logic       = template.logic;
 }
Пример #2
0
        internal List <List <string> > getPossibleSetOfLinks(string actionName, string exceptionStackTrace)
        {
            TransitionLink transitionLink = getTransitionLinkByTransitionLabel(actionName);

            if (transitionLink != null)
            {
                string logic = transitionLink.logic;
                // Check logic expression
                if (ExpressionParser.isValid(transitionLink))
                {
                    string[]              exp             = ExpressionParser.getDistribution(logic);
                    List <string>         groupLinksByAnd = new List <string> ();
                    List <List <string> > groupAndByOr    = new List <List <string> > ();
                    foreach (string s in exp)
                    {
                        if (!s.Equals("+") && !s.Equals("*"))
                        {
                            groupLinksByAnd.Add(s);
                        }
                        else if (s.Equals("+"))
                        {
                            groupAndByOr.Add(groupLinksByAnd);
                            groupLinksByAnd = new List <string> ();
                        }
                    }
                    groupAndByOr.Add(groupLinksByAnd);
                    return(groupAndByOr);
                }
                else
                {
                    throw new TraceAborted("Logic expression for \"" + actionName + "\" action in \"" + this.gameObject.name + "\" Game Object is not valid.", exceptionStackTrace);
                }
            }
            else
            {
                throw new TraceAborted("Action \"" + actionName + "\" is not monitored by \"" + this.gameObject.name + "\" Game Object.", exceptionStackTrace);
            }
        }
Пример #3
0
        internal string getInternalName(string actionName, string exceptionStackTrace, bool processLinks = true, params string[] linksConcerned)
        {
            TransitionLink transitionLink = getTransitionLinkByTransitionLabel(actionName);

            if (transitionLink != null)
            {
                string logic = transitionLink.logic;
                // Check logic expression
                if (ExpressionParser.isValid(transitionLink))
                {
                    List <List <string> > groupAndByOr = getPossibleSetOfLinks(actionName, exceptionStackTrace);

                    // If we have to process links and linksConcerned is empty and we have at least one OR statement into logic expression (i.e. at least 2 AND groups) => problem, developer has to specify the set of links concerned by this transition.
                    if (processLinks && linksConcerned.Length == 0 && groupAndByOr.Count > 1)
                    {
                        string availableCombination = "\nAvailable combination of links:\n";
                        foreach (List <string> ands in groupAndByOr)
                        {
                            availableCombination = availableCombination + " -";
                            foreach (string token in ands)
                            {
                                availableCombination = availableCombination + " " + token;
                            }
                            availableCombination = availableCombination + "\n";
                        }
                        throw new TraceAborted("Distributed logic expression for \"" + actionName + "\" action in \"" + this.gameObject.name + "\" Game Object contains \"+\" operator. You have to specify which links are concerned to perform this game action. " + availableCombination, exceptionStackTrace);
                    }
                    else
                    {
                        string prefix     = this.gameObject.name + "_";
                        bool   linksFound = false;
                        if (groupAndByOr.Count <= 1)
                        {
                            // If logic expression is empty or contains only AND operators, linksConcerned parameter is not useful because there is no ambiguity on this transition.
                            linksFound = true;
                            if (linksConcerned.Length
                                > 0)
                            {
                                WarningException we = new WarningException("Because logic expression includes only \"*\" operators, \"linksConcerned\" parameters are ignored. You can remove them to the call.", exceptionStackTrace);
                                Debug.LogException(we);
                            }
                        }
                        else
                        {
                            if (!processLinks)
                            {
                                // Developer wants to ignore linksConcerned. So we trace the first one (From Laalys point of view this is not a problem because all or actions have the same public name).
                                prefix     = "or0_" + prefix;
                                linksFound = true;
                            }
                            else
                            {
                                // Look for links concerned into distributed logic expression
                                List <string> linksConcerned_sorted = linksConcerned.ToList();
                                linksConcerned_sorted.Sort();
                                for (int i = 0; i < groupAndByOr.Count; i++)
                                {
                                    groupAndByOr [i].Sort();

                                    if (groupAndByOr [i].SequenceEqual(linksConcerned_sorted))
                                    {
                                        if (i > 0)
                                        {
                                            prefix = "or" + (i - 1) + "_" + prefix;
                                        }
                                        linksFound = true;
                                        break;
                                    }
                                }
                            }
                        }

                        if (linksFound)
                        {
                            return(prefix + actionName + "_" + this.id);
                        }
                        else
                        {
                            string debug = "";
                            foreach (string link in linksConcerned)
                            {
                                debug = debug + " \"" + link + "\"";
                            }

                            string availableCombination = "\nAvailable combination of links:\n";
                            foreach (List <string> ands in groupAndByOr)
                            {
                                availableCombination = availableCombination + " -";
                                foreach (string token in ands)
                                {
                                    availableCombination = availableCombination + " " + token;
                                }
                                availableCombination = availableCombination + "\n";
                            }
                            throw new TraceAborted(debug + " not found into distributed logic expression for \"" + actionName + "\" action in \"" + this.gameObject.name + "\" Game Object. " + availableCombination, exceptionStackTrace);
                        }
                    }
                }
                else
                {
                    throw new TraceAborted("Logic expression for \"" + actionName + "\" action in \"" + this.gameObject.name + "\" Game Object is not valid.", exceptionStackTrace);
                }
            }
            else
            {
                throw new TraceAborted("Action \"" + actionName + "\" is not monitored by \"" + this.gameObject.name + "\" Game Object.", exceptionStackTrace);
            }
        }
Пример #4
0
        /// <summary>Check if a transitionLink contains a valid logix expression.</summary>
        public static bool isValid(TransitionLink tLink)
        {
            string exp = tLink.logic;

            if (exp == null || exp.Length == 0)
            {
                return(true);
            }

            // Change all known link with true
            foreach (Link l in tLink.links)
            {
                if (!checkPrerequisite(l.label))
                {
                    return(false);
                }
                exp = Regex.Replace(exp, "^" + l.label + "$", "true");
                exp = Regex.Replace(exp, "^" + l.label + "([*+ ])", "true$1");
                exp = Regex.Replace(exp, "([(*+ ])(" + l.label + ")([)*+ ])", "$1true$3");
                exp = Regex.Replace(exp, "([(*+ ])(" + l.label + ")([)*+ ])", "$1true$3");                  // need to be done twice in case of (l1+l1) in this case "+" has to be used to replace "(l1+" and "+l1)" but Regex.Replace can't do this in a same replacement, only the first one is replaced.
                exp = Regex.Replace(exp, "([*+ ])" + l.label + "$", "$1true");
            }
            // Remove all spaces
            exp = exp.Replace(" ", "");
            // Try to resolve expression
            bool stable = false;

            do
            {
                string prevExp = exp;
                exp    = exp.Replace("true+true", "true");
                exp    = exp.Replace("true*true", "true");
                exp    = exp.Replace("(true)", "true");
                stable = prevExp == exp;
            } while (!stable);

            return(exp == "true");

            // Previous solution

            /*
             * int po = 0;
             * int pf = 0;
             * bool badOp = false;
             * char precedent = ' ';
             *
             * //manque vérif cohérence parenthèses
             * //vérif label ne peut pas être suivi ou précédé par un label
             *
             * foreach (char c in ari) {
             *
             *      if (!char.IsWhiteSpace (c)) {
             *              if (c == '(') {
             *                      po++;
             *              }
             *              if (c == ')') {
             *                      pf++;
             *              }
             *              if (((precedent == '(' || precedent == '*' || precedent == '+') && (c == '*' || c == '+')) || ((precedent == '*' || precedent == '+') && (c == ')' || c == '+' || c == '*'))) {
             *                      badOp = true;
             *              }
             *              precedent = c;
             *      }
             * }
             *
             * //Le début et la fin ne doivent pas être des opérateurs
             * if (ari[(ari.Length - 1)] == '+' || ari[(ari.Length - 1)] == '*' || ari[0] == '+' || ari[0] == '*')
             * badOp = true;
             *
             * return po == pf && !badOp;*/
        }