/// <summary> /// Takes the names, types etc. in DisplayBindings and uses reflection to find a PropertyInfo for them. /// Only call on start, or when something has been changed in the editor (NOT every frame) as it's heavy. /// </summary> public void BindToReflectedProperties() { //Call reflection once to get references to the properties for the displayers that aren't heavy later. for (int i = 0; i < _displayBindings.Count; i++) { //We have to replace the struct with a new one because we're stuck with structs because serialization. PropertyInfo newinfo = PartType.GetProperty(_displayBindings[i].PropertyName); DisplayPropBinding newbinding = new DisplayPropBinding { PropertyName = _displayBindings[i].PropertyName, Display = _displayBindings[i].Display, PropertyTypeString = _displayBindings[i].PropertyTypeString, Info = newinfo }; _displayBindings[i] = newbinding; } //Now call reflection for the control properties //ClearControlActionsByPart(); //Note that if this isn't done at start, you should've called ClearControlActionsByPart first so you don't get duplicates or leave actions on parts no longer bound. for (int i = 0; i < _controlBindings.Count; i++) { //We have to replace the struct with a new one because we're stuck with structs because serialization. PropertyInfo newinfo = PartType.GetProperty(_controlBindings[i].PropertyName); ControlPropBinding newbinding = new ControlPropBinding { PropertyName = _controlBindings[i].PropertyName, Control = _controlBindings[i].Control, PropertyTypeString = _controlBindings[i].PropertyTypeString, Info = newinfo }; _controlBindings[i] = newbinding; //Create and assign an action for setting the property to the control, if there is one. //TODO: Clean up past assignments. if (newbinding.Control) // { AssignSetterToControl(newbinding); } } }
/*/EditorGUILayout.PropertyField(_property); * * /SerializedProperty iterator = serializedObject.GetIterator(); * * bool next = iterator.NextVisible(true); * while(next) * { * if (iterator.propertyType == SerializedPropertyType.Float) * { * EditorGUILayout.PropertyField(iterator); * } * next = iterator.NextVisible(true); * } */ #endregion public void UpdatePropertyList() { Debug.Log("Updating property list"); _lastPartTarget = _partTarget; //Where we hold the values before checking them against the actual console's values disppropinfolist = new List <PropertyInfo>(); //For properties that are readable contpropinfolist = new List <PropertyInfo>(); //For properties that are writable Type parttype = _partConsole.PartType; if (parttype != null) { //You can't call reflection on null, so update with the blank lists PropertyInfo[] properties = parttype.GetProperties(); foreach (PropertyInfo info in properties) { if (info.DeclaringType == typeof(SomePart) || info.DeclaringType.IsSubclassOf(typeof(SomePart))) //SomePart would be the base part class in Hyperfusion { //Assign its getter to display properties, if there is one if (info.CanRead) { disppropinfolist.Add(info); } //Assign its setter to control properties, if there is one if (info.CanWrite) { contpropinfolist.Add(info); } } } } //Preserve the old settings so they don't get wiped out if they're common to a new part. //Doing this separately for readables and writables. Maybe there's a better way but I haven't thought of it yet. List <DisplayPropBinding> newdispbindings = new List <DisplayPropBinding>(); foreach (PropertyInfo info in disppropinfolist) { DisplayPropBinding binding = new DisplayPropBinding { PropertyName = info.Name, PropertyTypeString = info.PropertyType.ToString() }; newdispbindings.Add(binding); } //Now combine the old and new lists, so we can carry over old but valid properties. //_partConsole.DisplayBindings = newbindings; List <DisplayPropBinding> finaldispbindings = new List <DisplayPropBinding>(); List <DisplayPropBinding> badnewdispbindings = new List <DisplayPropBinding>(); foreach (DisplayPropBinding oldbinding in _partConsole.DisplayBindings) { foreach (DisplayPropBinding newbinding in newdispbindings) { if (newbinding.PropertyName == oldbinding.PropertyName) { //Take the old one, not the new one finaldispbindings.Add(oldbinding); //Add to the bad list to avoid adding the new version badnewdispbindings.Add(newbinding); } } } //Add the new ones that didn't have old counterparts added foreach (DisplayPropBinding newbinding in newdispbindings) { if (!badnewdispbindings.Contains(newbinding)) { finaldispbindings.Add(newbinding); } } _partConsole.DisplayBindings = finaldispbindings; //Now writable properties. List <ControlPropBinding> newcontbindings = new List <ControlPropBinding>(); foreach (PropertyInfo info in contpropinfolist) { ControlPropBinding binding = new ControlPropBinding { PropertyName = info.Name, PropertyTypeString = info.PropertyType.ToString() }; newcontbindings.Add(binding); } //Now combine the old and new lists, so we can carry over old but valid properties. //_partConsole.DisplayBindings = newbindings; List <ControlPropBinding> finalcontbindings = new List <ControlPropBinding>(); List <ControlPropBinding> badnewcontbindings = new List <ControlPropBinding>(); foreach (ControlPropBinding oldbinding in _partConsole.ControlBindings) { foreach (ControlPropBinding newbinding in newcontbindings) { if (newbinding.PropertyName == oldbinding.PropertyName) { //Take the old one, not the new one finalcontbindings.Add(oldbinding); //Add to the bad list to avoid adding the new version badnewcontbindings.Add(newbinding); } } } //Add the new ones that didn't have old counterparts added foreach (ControlPropBinding newbinding in newcontbindings) { if (!badnewcontbindings.Contains(newbinding)) { finalcontbindings.Add(newbinding); } } _partConsole.ControlBindings = finalcontbindings; serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { DrawDefaultInspector(); if (_partTarget != _lastPartTarget) { _partConsole.ClearControlActionsByPart(); UpdatePropertyList(); } bool updateruntimebindings = false; //If true, will call BindToReflectedProperties() at the end of the method //Display properties EditorGUILayout.Space(); EditorGUILayout.LabelField("Display Properties", EditorStyles.boldLabel); for (int i = 0; i < _partConsole.DisplayBindings.Count; i++) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(_partConsole.DisplayBindings[i].PropertyName); DisplayPropBinding tempbinding = new DisplayPropBinding { PropertyName = _partConsole.DisplayBindings[i].PropertyName, Display = EditorGUILayout.ObjectField(_partConsole.DisplayBindings[i].Display, PartConsole.GetDisplayType(_partConsole.DisplayBindings[i].PropertyTypeString), true) as ConsoleDisplay, PropertyTypeString = _partConsole.DisplayBindings[i].PropertyTypeString }; EditorGUILayout.EndHorizontal(); if (tempbinding.Display != _partConsole.DisplayBindings[i].Display) { _partConsole.DisplayBindings[i] = tempbinding; if (Application.isPlaying) { //_partConsole.BindToReflectedProperties(); updateruntimebindings = true; } } } ; //Control properties EditorGUILayout.Space(); EditorGUILayout.LabelField("Control Properties", EditorStyles.boldLabel); for (int i = 0; i < _partConsole.ControlBindings.Count; i++) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(_partConsole.ControlBindings[i].PropertyName); ControlPropBinding tempbinding = new ControlPropBinding { PropertyName = _partConsole.ControlBindings[i].PropertyName, Control = EditorGUILayout.ObjectField(_partConsole.ControlBindings[i].Control, PartConsole.GetControlType(_partConsole.ControlBindings[i].PropertyTypeString), true) as ConsoleControl, PropertyTypeString = _partConsole.ControlBindings[i].PropertyTypeString }; EditorGUILayout.EndHorizontal(); if (tempbinding.Control != _partConsole.ControlBindings[i].Control) { if (_partConsole.ControlBindings[i].Control != null) { _partConsole.ControlBindings[i].Control.DeregisterPart(_partConsole); } _partConsole.ControlBindings[i] = tempbinding; if (Application.isPlaying) { updateruntimebindings = true; } } } serializedObject.ApplyModifiedProperties(); if (updateruntimebindings) { _partConsole.ClearControlActionsByPart(); _partConsole.BindToReflectedProperties(); } }