예제 #1
0
        public static int maxCommandLength = 50;   //This is the maximum length of commands interpreted with this class. THis prevents locking up Unity

        /*!
         * Interpret a command
         * */
        public static MethodicalObject MakeChain(MonoBehaviour behaviour, string command)
        {
            safetyIndex = 0;            //resetting the safety index since we're starting a new interpretation
            MethodicalObject chain = Interpret(behaviour, null, command);

            PrintChain(chain);

            return(chain);
        }
예제 #2
0
        //************************** Utility methods **************************//

        #region Utility Methods

        private static void PrintChain(MethodicalObject chain)
        {
            string printedLine = "";

            foreach (MethodicalObject mo in chain)
            {
                printedLine = printedLine + "=>" + mo.objectName;
            }
            //Debug.Log(printedLine);
        }
예제 #3
0
        /*!
         * Processes a method into a chunk.
         * baseObject is the preprocessed chunk. Expects an objectname and objecttype to already be set.
         * */
        private static MethodicalObject ProcessMethodChunk(object context, MethodicalObject baseObject, string commandString)
        {
            string        argumentsString = GetNextArgumentsString(commandString);
            List <string> args            = SplitArguments(argumentsString);

            foreach (string argument in args)
            {
                baseObject.arguments.Add(Interpret(context, null, argument));
            }
            return(baseObject);
        }
예제 #4
0
        /*!
         * Recursively loop through command creating a data chain.
         * */
        private static MethodicalObject Interpret(object context, MethodicalObject chain, string command)
        {
            if (!validate(command))
            {
                return(new MethodicalErrorObject("", MethodicalErrorObject.ERRORTYPES.UnsupportedUsage));
            }

            //Doing some safety stuff to make sure I don't lock up Unity in an infinite loop
            if (safetyIndex > maxCommandLength)
            {
                return(null);               //TODO Make this return an error to the user.
            }
            safetyIndex++;

            //getting the next chunk
            MethodicalObject chunk = GetNextChunk(context, command);

            if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.equalityType))
            {
                //I can safely assume this is the first call of interpret
                chunk.leftEquality = Interpret(context, null, chunk.leftEqualityString);

                chunk.rightEquality = Interpret(context, null, chunk.rightEqualityString);
                return(chunk);
            }
            else
            {
                //going to shorten the command so the next chunk starts at the first character
                command = TruncateCommand(chunk, command);
                command = TrimPeriods(command);
                if (chain == null)                //starting chain if it isn't initiated, otherwise adding to chain
                {
                    chain = chunk;
                }
                else
                {
                    chain.AppendToChain(chunk);
                }
                //if there are any chunks left
                if (command != "")
                {
                    return(Interpret(context, chain, command));
                }
                return(chain);
            }
        }
예제 #5
0
        /*!
         * Takes in the latest chunk and the command string. Prepares the command string to retrieve the next chunk
         * */
        public static string TruncateCommand(MethodicalObject chunk, string command)
        {
            //trimming the string!
            int trimLength = 0;

            if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.arrayType))
            {
                trimLength = command.IndexOf("]") + 1;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.boolType))
            {
                trimLength = chunk.value.ToString().Length;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.floatType) || chunk.objectType.Equals(MethodicalObject.ObjectTypes.DoubleType))
            {
                trimLength = chunk.value.ToString().Length + 1;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.hashMapType))
            {
                trimLength = command.IndexOf("]") + 1;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.intType))
            {
                trimLength = chunk.objectName.Length;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.methodType))
            {
                string filterString = "(?<=\".*)[\\(\\),](?=.*\")";
                string fixedString  = ReplaceMatch(filterString, command, " ");
                int    startParen   = fixedString.IndexOf("(");
                int    lastParen    = GetClosingParen(startParen, fixedString);
                trimLength = lastParen + 1;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.stringType))
            {
                trimLength = chunk.value.ToString().Length + 2;
            }
            else if (chunk.objectType.Equals(MethodicalObject.ObjectTypes.variableType))
            {
                trimLength = chunk.objectName.Length;
            }

            command = command.Substring(trimLength, command.Length - trimLength);

            return(command);
        }
예제 #6
0
        public static object execute(MethodicalObject chain)
        {
            object newValue = null;

            if (chain != null && chain.objectType.Equals(MethodicalObject.ObjectTypes.equalityType))
            {
                newValue = execute(chain.rightEquality);
                return(execute(chain.leftEquality, newValue));
            }
            else
            {
                MethodicalObject currentLink = chain;
                object           lastReturn  = root;

                if (isStatic)
                {
                    if (currentLink.passesByValue)
                    {
                        lastReturn = currentLink.value;
                    }
                    else
                    {
                        lastReturn  = GetFromClass(root, staticRoot, lastReturn, currentLink);
                        currentLink = currentLink.member;
                    }
                }
                while (currentLink != null && lastReturn != null)
                {
                    if (currentLink.passesByValue)
                    {
                        lastReturn = currentLink.value;
                    }
                    else if (ExistsInClass(lastReturn, currentLink.objectName))
                    {
                        lastReturn = GetFromClass(root, staticRoot, lastReturn, currentLink);
                    }
                    else
                    {
                        return(new MethodicalErrorObject(currentLink.objectName, MethodicalErrorObject.ERRORTYPES.DoesNotExist));
                    }
                    currentLink = currentLink.member;
                }
                return(lastReturn);
            }
        }
예제 #7
0
        /*!
         * Calls commands to the selected monobehaviour using invoke
         *
         * */
        private void CallCommand()
        {
            if (go == null)
            {
                //display.Insert(0,new MethodicalMessage("No monobehavior selected!",MethodicalMessage.MessageTypes.Error));
                //return;
            }
            if (command.Equals(""))
            {
                display.Insert(0, new MethodicalMessage("No command entered!", MethodicalMessage.MessageTypes.Error));
                return;
            }
            commandCalled = true;
            MethodicalExecutor.isStatic   = staticMode;
            MethodicalExecutor.root       = go;
            MethodicalExecutor.staticRoot = staticVariable;

            MethodicalObject chain = MethodicalInterpreter.MakeChain(go, command);



            object returnValue = MethodicalExecutor.execute(chain);

            commands.Insert(0, command);
            display.Insert(0, command);
            if (chain.GetType().Equals(typeof(MethodicalErrorObject)))
            {
                display.Insert(0, new MethodicalMessage(chain.ToString(), MethodicalMessage.MessageTypes.Error));
            }
            else if (returnValue != null && returnValue.GetType().Equals(typeof(MethodicalErrorObject)))
            {
                display.Insert(0, new MethodicalMessage(returnValue.ToString(), MethodicalMessage.MessageTypes.Error));
            }
            else if (returnValue != null)
            {
                display.Insert(0, new MethodicalMessage("-     " + returnValue, MethodicalMessage.MessageTypes.Return));
            }
            command       = "";
            commandIndex  = -1;
            cachedCommand = "";
            EditorGUI.FocusTextInControl("MethodicalCommandField");
        }
예제 #8
0
        private static object execute(MethodicalObject chain, object assignValue)
        {
            MethodicalObject currentLink = chain;
            object           lastReturn  = root;

            while (currentLink != null && lastReturn != null)
            {
                if (ExistsInClass(lastReturn, currentLink.objectName))
                {
                    lastReturn = SetFromClass(root, staticRoot, lastReturn, currentLink, assignValue);
                    if (lastReturn == null || !lastReturn.GetType().Equals(typeof(MethodicalErrorObject)))
                    {
                        lastReturn = assignValue;                        // just going to print out the assigned value
                    }
                }
                else
                {
                    return(new MethodicalErrorObject(currentLink.objectName, MethodicalErrorObject.ERRORTYPES.DoesNotExist));
                }
                currentLink = currentLink.member;
            }
            return(lastReturn);
        }
예제 #9
0
        private static MethodicalErrorObject SetFromClass(MonoBehaviour root, string staticRoot, object parentObject, MethodicalObject member, object newValue)
        {
            //Going to try to get each as a field, a property, or method and see what sticks
            FieldInfo    field    = null;
            PropertyInfo property = null;

            //MethodInfo method = null;
            if (isStatic && parentObject == null)               //Then static
            {
                System.Type type = GetTypeByName(staticRoot);
                field    = type.GetField(member.objectName);
                property = type.GetProperty(member.objectName);
                //method = type.GetMethod(member.objectName);
            }
            else
            {
                field    = MatchField(parentObject.GetType(), member.objectName);
                property = MatchProperty(parentObject.GetType(), member.objectName);
                //method = MatchMethod(parentObject.GetType(), member.objectName);
            }


            if (field != null)              //Ugly and pointlessly verbose but readable

            {
                if (member.objectType.Equals(MethodicalObject.ObjectTypes.arrayType))                  //If array
                //Getting the array
                {
                    object[] array = (object[])field.GetValue(parentObject);
                    int      index = (int)execute(member.arrayDictionaryIndex);
                    //Checking bounds
                    if (index < 0 || index >= array.Length)
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.OutOfBounds));
                    }
                    //Making sure the types match
                    if (!array.GetType().ToString().Equals(newValue.GetType().ToString() + "[]"))
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.TypeMismatch));
                    }

                    //Getting the array value
                    array.SetValue(newValue, index);
                }
                else if (member.objectType.Equals(MethodicalObject.ObjectTypes.hashMapType))
                {
                    object index = (object)execute(member.arrayDictionaryIndex);
                    if (index.GetType().Equals(typeof(MethodicalErrorObject)))                      //escaping of index variable doesn't exist
                    {
                        return((MethodicalErrorObject)index);
                    }

                    /*object value = field.FieldType.GetMethod("get_Item")
                     *      .Invoke(field.GetValue(parentObject), new object[] { index });*/
                    //Debug.Log("return value: " + value);
                    Debug.Log("How did I get here?");
                    //field.SetValue(index, newValue);//TODO figure out if this works?!?!
                }
                else
                {
                    field.SetValue(root, newValue);                   //TODO figure out what to do here
                }
            }
            else if (property != null)
            {
                if (member.objectType.Equals(MethodicalObject.ObjectTypes.arrayType))                  //If array
                //Getting the array
                {
                    object[] array = (object[])property.GetValue(parentObject, null);
                    int      index = (int)execute(member.arrayDictionaryIndex);
                    //Checking bounds
                    if (index < 0 || index >= array.Length)
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.OutOfBounds));
                    }
                    //Making sure the types match
                    if (!array.GetType().ToString().Equals(newValue.GetType().ToString() + "[]"))
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.TypeMismatch));
                    }
                    //Getting the array value
                    array.SetValue(newValue, index);
                }
                else if (member.objectType.Equals(MethodicalObject.ObjectTypes.hashMapType))
                {
                    object index = (object)execute(member.arrayDictionaryIndex);
                    if (index.GetType().Equals(typeof(MethodicalErrorObject)))                      //escaping of index variable doesn't exist
                    {
                        return((MethodicalErrorObject)index);
                    }
                    property.PropertyType.GetMethod("get_Item")
                    .Invoke(property.GetValue(parentObject, null), new object[] { index });
                    //Debug.Log("return value: " + value);
                    Debug.Log("How did I get here?");
                    //return value;
                }
                else
                {
                    //return property.GetValue(parentObject, null);
                    property.SetValue(parentObject, newValue, null);
                }
            }

            return(null);
        }
예제 #10
0
        /*!
         * Get the member object from the given class in the given context(root) and evaluates
         * */
        private static object GetFromClass(MonoBehaviour root, string staticRoot, object parentObject, MethodicalObject member)
        {
            //Going to try to get each as a field, a property, or method and see what sticks
            FieldInfo    field    = null;
            PropertyInfo property = null;
            MethodInfo   method   = null;

            if (isStatic && parentObject == null)               //Then static
            {
                System.Type type = GetTypeByName(staticRoot);
                field    = type.GetField(member.objectName);
                property = type.GetProperty(member.objectName);
                method   = type.GetMethod(member.objectName);
            }
            else
            {
                field    = MatchField(parentObject.GetType(), member.objectName);
                property = MatchProperty(parentObject.GetType(), member.objectName);
                method   = MatchMethod(parentObject.GetType(), member.objectName);
            }


            // Doing fields now
            if (field != null)           //Ugly and pointlessly verbose but readable

            // Array Field
            {
                if (member.objectType.Equals(MethodicalObject.ObjectTypes.arrayType))                 //If array
                //Getting the array
                {
                    object[] array = (object[])field.GetValue(parentObject);
                    int      index = (int)execute(member.arrayDictionaryIndex);
                    //Checking bounds
                    if (index < 0 || index >= array.Length)
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.OutOfBounds));
                    }

                    //Getting the array value
                    return(array.GetValue(index));

                    //Hashmap Field
                }
                else if (member.objectType.Equals(MethodicalObject.ObjectTypes.hashMapType))
                {
                    object index = (object)execute(member.arrayDictionaryIndex);
                    if (index.GetType().Equals(typeof(MethodicalErrorObject)))                     //escaping of index variable doesn't exist
                    {
                        return(index);
                    }


                    //Checking the index type. Messy, but it works I guess
                    if (!field.FieldType.ToString().Contains("[" + index.GetType().ToString()) &&
                        field.FieldType.ToString().Contains("System.Collections.Generic.Dictionary"))
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.TypeMismatch));
                    }
                    object value = field.FieldType.GetMethod("get_Item")
                                   .Invoke(field.GetValue(parentObject), new object[] { index });
                    //Debug.Log("return value: " + value);

                    return(value);

                    //Just a normal field
                }
                else
                {
                    return(field.GetValue(parentObject));
                }

                //Getting props
            }
            else if (property != null)
            {
                // Getting array members
                if (member.objectType.Equals(MethodicalObject.ObjectTypes.arrayType))                 //If array
                //Getting the array
                {
                    object[] array = (object[])property.GetValue(parentObject, null);
                    int      index = (int)execute(member.arrayDictionaryIndex);
                    //Checking bounds
                    if (index < 0 || index >= array.Length)
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.OutOfBounds));
                    }

                    //Getting the array value
                    return(array.GetValue(index));

                    // Getting hashmap member
                }
                else if (member.objectType.Equals(MethodicalObject.ObjectTypes.hashMapType))
                {
                    object index = (object)execute(member.arrayDictionaryIndex);
                    if (index.GetType().Equals(typeof(MethodicalErrorObject)))                     //escaping of index variable doesn't exist
                    {
                        return(index);
                    }

                    //Checking the index type. Messy, but it works I guess
                    if (!field.FieldType.ToString().Contains("[" + index.GetType().ToString()) &&
                        field.FieldType.ToString().Contains("System.Collections.Generic.Dictionary"))
                    {
                        return(new MethodicalErrorObject(member.objectName, MethodicalErrorObject.ERRORTYPES.TypeMismatch));
                    }
                    object value = property.PropertyType.GetMethod("get_Item")
                                   .Invoke(property.GetValue(parentObject, null), new object[] { index });
                    //Debug.Log("return value: " + value);

                    return(value);

                    //Just a regular member
                }
                else
                {
                    return(property.GetValue(parentObject, null));
                }

                // It's a method!
            }
            else if (method != null)
            {
                List <object> parameters = new List <object>();

                //Evaluating each argument and turn them into something usable for reflection
                foreach (MethodicalObject mo in member.arguments)
                {
                    object param = execute(mo);
                    parameters.Add(param);
                }

                if (parameters.Count != method.GetParameters().Length)
                {
                    return(new MethodicalErrorObject(method.Name, MethodicalErrorObject.ERRORTYPES.BadArguments));
                }
                else                  //Then both parameter counts should be equal, no need to check
                {
                    for (int i = 0; i < parameters.Count; i++)
                    {
                        if (parameters[i] != null && !method.GetParameters()[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
                        {
                            return(new MethodicalErrorObject(method.Name, MethodicalErrorObject.ERRORTYPES.BadArguments));
                        }
                    }
                }
                return(method.Invoke(parentObject, parameters.ToArray()));

                //Well no clue what it is then...
            }
            else
            {
                return(null);
            }
        }
예제 #11
0
        /*!
         * This method takes an input string, gets the next chunk, and prepares the string
         * for retrieval of the next chunk by removing the chunk that was just found
         * */
        private static MethodicalObject GetNextChunk(object context, string command)
        {
            //Getting next chunk
            MethodicalObject chunk        = new MethodicalObject();
            string           methodReturn = "";

            string[] equality = new string[0];
            if ((equality = CheckEquality(command)) != null)
            {
                chunk.objectName          = "equality";
                chunk.objectType          = MethodicalObject.ObjectTypes.equalityType;
                chunk.leftEqualityString  = equality[0];
                chunk.leftEqualityString  = chunk.leftEqualityString.Trim();
                chunk.rightEqualityString = equality[1];
                chunk.rightEqualityString = chunk.rightEqualityString.Trim();
            }
            else if ((methodReturn = CheckNumber(command)) != "")              //is the next chunk a number?

            {
                chunk.objectName = methodReturn;                //I'll never use this, but it makes printlines readable
                //float or int?
                if (methodReturn.Contains("f") || methodReturn.Contains("F"))
                {
                    chunk.objectType = MethodicalObject.ObjectTypes.floatType;
                    methodReturn     = methodReturn.Replace("f", "");
                    methodReturn     = methodReturn.Replace("F", "");
                    chunk.value      = float.Parse(methodReturn);
                }
                else if (methodReturn.Contains("d") || methodReturn.Contains("D"))
                {
                    chunk.objectType = MethodicalObject.ObjectTypes.DoubleType;
                    methodReturn     = methodReturn.Replace("d", "");
                    methodReturn     = methodReturn.Replace("D", "");
                    chunk.value      = double.Parse(methodReturn);
                }
                else
                {
                    chunk.objectType = MethodicalObject.ObjectTypes.intType;
                    chunk.value      = int.Parse(methodReturn);
                }
            }
            else if ((methodReturn = CheckBool(command)) != "")              //is the next chunk a boolean?

            {
                chunk.objectName = methodReturn;                //I'll never use this, but it makes printlines readable
                chunk.value      = bool.Parse(methodReturn);
                chunk.objectType = MethodicalObject.ObjectTypes.boolType;
            }
            else if ((methodReturn = CheckString(command)) != "")              //is the next chunk a string?

            {
                chunk.objectName = methodReturn;
                chunk.objectType = MethodicalObject.ObjectTypes.stringType;
                methodReturn     = methodReturn.Trim('"');
                chunk.value      = methodReturn;
            }
            else if ((methodReturn = CheckArray(context, command)) != "")              //is the next chunk an array?

            {
                chunk.objectName           = methodReturn;
                chunk.objectType           = MethodicalObject.ObjectTypes.arrayType;
                chunk.arrayDictionaryIndex = Interpret(context, null, GetArrayIndex(command));
                //testIndex = new MethodicalObject();
                //testIndex.value = 0;
                //testIndex.objectName = "0";
                //testIndex.objectType = MethodicalObject.ObjectTypes.arrayType;
                //chunk.arrayDictionaryIndex = new MethodicalObject ();
            }
            else if ((methodReturn = CheckHashMap(context, command)) != "")             //is the next chunk a hashmap?

            {
                chunk.objectName           = methodReturn;
                chunk.objectType           = MethodicalObject.ObjectTypes.hashMapType;
                chunk.arrayDictionaryIndex = Interpret(context, null, GetHashmapIndex(command));
            }
            else if ((methodReturn = CheckMethod(command)) != "")              //is the next chunk a method?
            {
                chunk.objectName = methodReturn;
                chunk.objectType = MethodicalObject.ObjectTypes.methodType;
                ProcessMethodChunk(context, chunk, command);                // doing some additional processing
            }
            else if ((methodReturn = CheckVariable(command)) != "")         //is the next chunk a variable?
            {
                chunk.objectName = methodReturn;
                chunk.objectType = MethodicalObject.ObjectTypes.variableType;
            }


            return(chunk);
        }