示例#1
0
    private void UpdateBindings()
    {
        List <MethodInfo> dispmethods = new List <MethodInfo>();
        List <MethodInfo> contmethods = new List <MethodInfo>();

        //We'll make custom bindings for each - except if the current bindings list already has a binding that matches the name and type.
        List <DisplayBinding> finaldispbinds = new List <DisplayBinding>();
        List <ControlBinding> finalcontbinds = new List <ControlBinding>();

        //Stop if we don't have a script
        if (_script != null)
        {
            //Iterate through methods and assign relevant ones to bindings list
            MethodInfo[] methods = _scriptType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
            for (int i = 0; i < methods.Length; i++)
            {
                //Don't do anything if it's part of MonoBehaviour, because the developer didn't add that.
                if (methods[i].DeclaringType.IsAssignableFrom(typeof(MonoBehaviour)))
                {
                    continue;
                }

                //Assign everything into a relevant list, if there is one.
                if (methods[i].ReturnType == typeof(void))
                {
                    //No return type. It can fit a control.
                    contmethods.Add(methods[i]);
                }
                else if (methods[i].GetParameters().Length == 0)
                {
                    //It has a return, but takes no parameters. It's either a getter or a method made to act like one.
                    dispmethods.Add(methods[i]);
                }
            }

            //Now we've got all the methods that need bindings.


            //Display first.
            foreach (MethodInfo info in dispmethods)
            {
                bool foundoldmatch = false;
                //Check existing bindings for both names and return types.
                foreach (DisplayBinding oldbinding in _console.DisplayBindingsList)
                {
                    if (oldbinding.MethodName == info.Name && _scriptType.GetMethod(oldbinding.MethodName).ReturnType == info.ReturnType)
                    {
                        //It's a match. Pass in the old one.
                        finaldispbinds.Add(oldbinding);
                        foundoldmatch = true;
                        break;
                    }
                }

                if (foundoldmatch == false)
                {
                    DisplayBinding newdisp = new DisplayBinding
                    {
                        MethodName = info.Name,
                        TypeString = info.ReturnType.Name
                    };

                    finaldispbinds.Add(newdisp);
                }
            }

            //Now Control.
            foreach (MethodInfo info in contmethods)
            {
                bool            foundoldmatch = false;
                ParameterInfo[] newparams     = info.GetParameters(); // Caching because we'll compare a lot.
                                                                      //Check existing bindings for both names and parameters.
                foreach (ControlBinding oldbinding in _console.ControlBindingsList)
                {
                    //if (oldbinding.MethodName == info.Name && _scriptType.GetMethod(oldbinding.MethodName).GetParameters() == newparams)
                    if (oldbinding.MethodName == info.Name)
                    {
                        //The names match. Make sure the parameter types match.
                        ParameterInfo[] oldparams = _scriptType.GetMethod(oldbinding.MethodName).GetParameters();

                        if (newparams.Length != oldparams.Length)
                        {
                            continue;
                        }

                        bool foundbadparam = false;
                        for (int i = 0; i < newparams.Length; i++)
                        {
                            if (newparams[i].ParameterType != oldparams[i].ParameterType)
                            {
                                foundbadparam = true;
                            }
                        }
                        if (foundbadparam)
                        {
                            continue;
                        }


                        //It's a match. Pass in the old one.
                        finalcontbinds.Add(oldbinding);
                        foundoldmatch = true;
                        break;
                    }
                }

                if (foundoldmatch == false)
                {
                    //Make a string that lists the parameters for easy display
                    string paramstring = "";
                    for (int i = 0; i < newparams.Length; i++)
                    {
                        paramstring += newparams[i].ParameterType.Name;
                        if (i < newparams.Length - 1)
                        {
                            paramstring += ", ";
                        }
                    }
                    ControlBinding newcont = new ControlBinding
                    {
                        MethodName  = info.Name,
                        ParamString = paramstring
                    };

                    finalcontbinds.Add(newcont);
                }
            }
        }
        //Replace the console's list with ours.
        _console.DisplayBindingsList = finaldispbinds;
        _console.ControlBindingsList = finalcontbinds;
    }
示例#2
0
    public override void OnInspectorGUI()
    {
        //DrawDefaultInspector();

        if (_script != _lastScript)
        {
            //The script got changed, clean house.
            UpdateBindings();
            _lastScript = _script;
        }

        //Don't allow changing the target script during runtime
        EditorGUI.BeginDisabledGroup(Application.isPlaying);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Target Monoscript: ", EditorStyles.boldLabel);
        _script = (MonoScript)EditorGUILayout.ObjectField(_script, typeof(MonoScript), false, null);
        EditorGUILayout.EndHorizontal();
        EditorGUI.EndDisabledGroup();

        //Target component
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Runtime Component: ", EditorStyles.boldLabel);
        //_console.RuntimeScript = (Component)EditorGUILayout.ObjectField(_console.RuntimeScript, _scriptType, true, null);
        Component newcomponent = (Component)EditorGUILayout.ObjectField(_console.RuntimeScript, _scriptType, true, null);

        if (newcomponent != _console.RuntimeScript)
        {
            _console.ChangeRuntimeScript(newcomponent);
        }



        //Display bindings
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Display Properties", EditorStyles.boldLabel);

        for (int i = 0; i < _console.DisplayBindingsList.Count; i++)
        {
            DisplayBinding dbind = _console.DisplayBindingsList[i]; //Shorthand

            EditorGUILayout.BeginHorizontal();

            //Figure out the BaseDisplay type
            Type generic     = typeof(BaseDisplay <>);
            Type constructed = generic.MakeGenericType(new Type[1] {
                _scriptType.GetMethod(dbind.MethodName).ReturnType
            });                                                                           //This gets called most every frame, so would be nice to optimize later.

            EditorGUILayout.LabelField(dbind.MethodName + " <" + dbind.TypeString + ">"); //Adding type in label since the object field won't show it properly due to serialization

            BaseDisplay basedisp = (BaseDisplay)EditorGUILayout.ObjectField(dbind.Display, constructed, true, null);

            EditorGUILayout.EndHorizontal();

            //If the bound object has changed, inject this binding in place of the old one.
            if (dbind.Display != basedisp)
            {
                DisplayBinding replacebind = new DisplayBinding
                {
                    MethodName = dbind.MethodName,
                    Display    = basedisp,
                    TypeString = dbind.TypeString
                };
                _console.DisplayBindingsList[i] = replacebind;
                Debug.Log("Replaced");
            }
        }

        //Control bindings
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Control Properties/Methods", EditorStyles.boldLabel);

        for (int i = 0; i < _console.ControlBindingsList.Count; i++)
        {
            ControlBinding cbind = _console.ControlBindingsList[i]; //Shorthand
            EditorGUILayout.BeginHorizontal();

            //Figure out the BaseControl type
            Type            generic    = typeof(BaseControl <>);
            ParameterInfo[] paramsinfo = _scriptType.GetMethod(cbind.MethodName).GetParameters();
            Type            newtype    = (paramsinfo.Length > 0) ? paramsinfo[0].ParameterType : typeof(void);

            Type constructed = generic.MakeGenericType(new Type[1] {
                newtype
            });                                                                            //This gets called most every frame, so would be nice to optimize later. //WRONG fix later

            EditorGUILayout.LabelField(cbind.MethodName + " <" + cbind.ParamString + ">"); //Adding type in label since the object field won't show it properly due to serialization

            BaseControl basecont = (BaseControl)EditorGUILayout.ObjectField(cbind.Control, constructed, true, null);

            EditorGUILayout.EndHorizontal();

            //If the bound object has changed inject this binding in place of old one.
            if (cbind.Control != basecont)
            {
                ControlBinding replacebind = new ControlBinding
                {
                    MethodName  = cbind.MethodName,
                    Control     = basecont,
                    ParamString = cbind.ParamString
                };
                _console.ControlBindingsList[i] = replacebind;
                Debug.Log("Replaced");
            }
        }
    }