/// <summary> /// Changes the instance of the given object, if necessary. /// </summary> public object UpdateObjectInstance(object current, int currentIndex, int updatedIndex) { // the index has not changed - there will be no change in object instance if (currentIndex == updatedIndex) { return(current); } // index 0 is always null if (updatedIndex == 0) { return(null); } // create an instance of the object Type type = _options[updatedIndex - 1].RawType; return(InspectedType.Get(type).CreateInstance()); }
//protected List<FieldInfo> Fields { get; set; } protected virtual void OnEnable() { InspectedObject = serializedObject.targetObject; InspectedType = InspectedObject.GetType(); Properties = InspectedType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(property => property.DeclaringType == InspectedType) .Where(property => (property.SetMethod?.IsPublic).GetValueOrDefault()) .ToList(); //Fields = InspectedType // .GetFields(BindingFlags.Public | BindingFlags.Instance) // .Concat(InspectedType // .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) // .Where(field => field.GetCustomAttribute<SerializeField>() != null) // ) // .Where(field => field.IsInitOnly == false) // .ToList(); }
private static fiGraphMetadata EnsureInitialState(tkDatabaseContext context, fiGraphMetadata metadata) { if (context.editedList == null) { context.editedList = (IList)InspectedType.Get(typeof(TDerived)).CreateInstance(); } InspectorDatabaseEditorMetadata databaseMetadata = metadata.GetMetadata <InspectorDatabaseEditorMetadata>(); // Set the global metadata to the graph metadata, as the graph // metadata is persistent but users still may want to access the // global metadata. fiGlobalMetadata.Set(context.editedList, databaseMetadata); // Disable the dropdown metadata.GetPersistentMetadata <fiDropdownMetadata>().ForceDisable(); TryEnsureValidIndex(context); return(metadata.Enter(databaseMetadata.CurrentIndex, context.editedList).Metadata); }
static TypeSelectionPopupWindow() { _allTypesWithStatics = new List <Type>(); foreach (Assembly assembly in fiRuntimeReflectionUtility.GetUserDefinedEditorAssemblies()) { foreach (Type type in assembly.GetTypesWithoutException()) { var inspected = InspectedType.Get(type); if (inspected.IsCollection == false) { _allTypesWithStatics.Add(type); } } } _allTypesWithStatics = (from type in _allTypesWithStatics orderby type.CSharpName() orderby type.Namespace select type).ToList(); }
/// <summary> /// Restores a backup that was previously created. /// </summary> public static void RestoreBackup(fiSerializedObject serializedState) { Type targetType = serializedState.Target.Target.GetType(); var inspectedType = InspectedType.Get(targetType); var serializationOperator = new fiSerializationOperator() { SerializedObjects = serializedState.ObjectReferences }; // Fetch the serializer that the target uses Type serializerType = BehaviorTypeToSerializerTypeMap.GetSerializerType(targetType); var serializer = (BaseSerializer)fiSingletons.Get(serializerType); foreach (fiSerializedMember member in serializedState.Members) { // user requested a skip for restoring this property if (member.ShouldRestore.Enabled == false) { continue; } InspectedProperty property = inspectedType.GetPropertyByName(member.Name); if (property != null) { Type storageType = property.StorageType; object restoredValue = serializer.Deserialize(storageType, member.Value, serializationOperator); property.Write(serializedState.Target.Target, restoredValue); } } if (serializedState.Target.Target is ISerializedObject) { var serializedObj = ((ISerializedObject)serializedState.Target.Target); serializedObj.SaveState(); serializedObj.RestoreState(); } }
private static bool TryToCopyValues(ISerializedObject newInstance) { if (string.IsNullOrEmpty(newInstance.SharedStateGuid)) { return(false); } ISerializedObject originalInstance = null; lock (_skipSerializationQueue) { if (!_skipSerializationQueue.TryGetValue(newInstance.SharedStateGuid, out originalInstance)) { return(false); } _skipSerializationQueue.Remove(newInstance.SharedStateGuid); } // After a prefab is instantiated Unity will call a full // serialize/deserialize cycle on the object. We don't need to copy // values if the object references are the same. if (ReferenceEquals(newInstance, originalInstance)) { return(true); } var inspectedType = InspectedType.Get(originalInstance.GetType()); for (int i = 0; i < originalInstance.SerializedStateKeys.Count; ++i) { InspectedProperty property = inspectedType.GetPropertyByName(originalInstance.SerializedStateKeys[i]) ?? inspectedType.GetPropertyByFormerlySerializedName(originalInstance.SerializedStateKeys[i]); property.Write(newInstance, property.Read(originalInstance)); } return(true); }
/// <summary> /// Deserializes an object that has been serialized. /// </summary> /// <typeparam name="TSerializer"> /// The type of serializer that was used to serialize the object. /// </typeparam> /// <param name="obj"> /// The object that will be restored from its serialized state. /// </param> /// <returns> /// True if restoration was completely successful, false if something bad /// happened at some point (the object may be in a partially deserialized /// state). /// </returns> public static bool RestoreState <TSerializer>(ISerializedObject obj) where TSerializer : BaseSerializer { fiLog.Log(typeof(fiISerializedObjectUtility), "Deserializing object of type {0}", obj.GetType()); var callbacks = obj as ISerializationCallbacks; try { if (callbacks != null) { callbacks.OnBeforeDeserialize(); } // Use fast-path that does not do object serialization if the // user requested it. if (!string.IsNullOrEmpty(obj.SharedStateGuid)) { if (obj.IsRestored) { return(true); } if (TryToCopyValues(obj)) { fiLog.Log(typeof(fiISerializedObjectUtility), "-- note: Used fast path when deserializing object of type {0}", obj.GetType()); obj.IsRestored = true; if (callbacks != null) { callbacks.OnAfterDeserialize(); } return(true); } else { Debug.LogError("Shared state deserialization failed for object of type " + obj.GetType().CSharpName(), obj as UnityObject); } } // ensure references are initialized if (obj.SerializedStateKeys == null) { obj.SerializedStateKeys = new List <string>(); } if (obj.SerializedStateValues == null) { obj.SerializedStateValues = new List <string>(); } if (obj.SerializedObjectReferences == null) { obj.SerializedObjectReferences = new List <UnityObject>(); } // try to verify that no data corruption occurred if (obj.SerializedStateKeys.Count != obj.SerializedStateValues.Count) { if (fiSettings.EmitWarnings) { Debug.LogWarning("Serialized key count does not equal value count; possible " + "data corruption / bad manual edit?", obj as UnityObject); } } // there is nothing to deserialize if (obj.SerializedStateKeys.Count == 0) { if (fiSettings.AutomaticReferenceInstantation) { InstantiateReferences(obj, null); } obj.IsRestored = true; return(true); } // fetch the selected serializer var serializer = fiSingletons.Get <TSerializer>(); // setup the serialization operator setup the serialization // operator var serializationOperator = fiSingletons.Get <ListSerializationOperator>(); serializationOperator.SerializedObjects = obj.SerializedObjectReferences; // get the properties that we will be serializing var inspectedType = InspectedType.Get(obj.GetType()); bool success = true; for (int i = 0; i < obj.SerializedStateKeys.Count; ++i) { var name = obj.SerializedStateKeys[i]; var state = obj.SerializedStateValues[i]; var property = inspectedType.GetPropertyByName(name) ?? inspectedType.GetPropertyByFormerlySerializedName(name); if (property == null) { if (fiSettings.EmitWarnings) { Debug.LogWarning("Unable to find serialized property with name=" + name + " on type " + obj.GetType(), obj as UnityObject); } continue; } object restoredValue = null; if (string.IsNullOrEmpty(state) == false) { try { restoredValue = serializer.Deserialize(property.MemberInfo, state, serializationOperator); } catch (Exception e) { success = false; Debug.LogError("Exception caught when deserializing property <" + name + "> with type <" + obj.GetType() + ">\n" + e, obj as UnityObject); } } // sigh... CompareBaseObjectsExternal exception is thrown when we write a null // UnityObject reference in a non-primary thread using reflection // // This is commented out because we're not currently doing multithreaded // deserialization, but this was a tricky issue to find so it will remain // documented here. // // Please note that this breaks Reset() when there is a generic UnityObject // type on the BaseBehavior, ie, // class MyBehavior : BaseBehavior { public SharedInstance<int> myInt; } // //if (ReferenceEquals(restoredValue, null) && // typeof(UnityObject).IsAssignableFrom(property.StorageType)) { // continue; //} try { property.Write(obj, restoredValue); } catch (Exception e) { success = false; if (fiSettings.EmitWarnings) { Debug.LogWarning( "Caught exception when updating property value; see next message for the exception", obj as UnityObject); Debug.LogError(e); } } } obj.IsRestored = true; return(success); } finally { if (callbacks != null) { callbacks.OnAfterDeserialize(); } } }
/// <summary> /// Serializes the current state of the given object. /// </summary> /// <typeparam name="TSerializer"> /// The type of serializer to use for the serialization process. /// </typeparam> /// <param name="obj">The object that should be serialized.</param> /// <returns> /// True if serialization was entirely successful, false if something bad /// happened along the way. /// </returns> public static bool SaveState <TSerializer>(ISerializedObject obj) where TSerializer : BaseSerializer { fiLog.Log(typeof(fiISerializedObjectUtility), "Serializing object of type {0}", obj.GetType()); bool success = true; var callbacks = obj as ISerializationCallbacks; if (callbacks != null) { callbacks.OnBeforeSerialize(); } // Skip serialization entirely if requested. if (!string.IsNullOrEmpty(obj.SharedStateGuid)) { SkipCloningValues(obj); if (callbacks != null) { callbacks.OnAfterSerialize(); } return(true); } // fetch the selected serializer var serializer = fiSingletons.Get <TSerializer>(); // setup the serialization operator var serializationOperator = fiSingletons.Get <ListSerializationOperator>(); serializationOperator.SerializedObjects = new List <UnityObject>(); // get the properties that we will be serializing var serializedKeys = new List <string>(); var serializedValues = new List <string>(); // PERF: Calling InspectedType().GetProperties() is extremely // expensive. If we're not in the editor, then we can avoid // making that call because the only time we serialize an // object is if it has existing FS data. If it has FS data, // then that data stores the set of properties which are // serialized, so we can just hijack that information when // doing the serialization to determine which properties to // serialize. if (fiUtility.IsEditor || obj.SerializedStateKeys == null || obj.SerializedStateKeys.Count == 0) { var properties = InspectedType.Get(obj.GetType()).GetProperties(InspectedMemberFilters.FullInspectorSerializedProperties); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; string serializedValue; if (SaveStateForProperty(obj, property, serializer, serializationOperator, out serializedValue, ref success)) { serializedKeys.Add(property.Name); serializedValues.Add(serializedValue); } } } else { var inspectedType = InspectedType.Get(obj.GetType()); for (int i = 0; i < obj.SerializedStateKeys.Count; ++i) { InspectedProperty property = inspectedType.GetPropertyByName(obj.SerializedStateKeys[i]) ?? inspectedType.GetPropertyByFormerlySerializedName(obj.SerializedStateKeys[i]); if (property == null) { continue; } string serializedValue; if (SaveStateForProperty(obj, property, serializer, serializationOperator, out serializedValue, ref success)) { serializedKeys.Add(property.Name); serializedValues.Add(serializedValue); } } } // Write the updated data out to the object. // Note that we only write data out to the object if our serialized // state has changed. Unity will blindly rewrite the data on disk // which will cause some source control systems to check-out the // files. If we are just updating the content to the same content, we // do not want to cause an accidental checkout. bool changed = false; if (AreListsDifferent(obj.SerializedStateKeys, serializedKeys)) { obj.SerializedStateKeys = serializedKeys; changed = true; } if (AreListsDifferent(obj.SerializedStateValues, serializedValues)) { obj.SerializedStateValues = serializedValues; changed = true; } if (AreListsDifferent(obj.SerializedObjectReferences, serializationOperator.SerializedObjects)) { obj.SerializedObjectReferences = serializationOperator.SerializedObjects; changed = true; } if (changed && fiUtility.IsEditor) { fiLateBindings.EditorApplication.InvokeOnEditorThread(() => { var unityObj = (UnityObject)obj; if (unityObj != null) { fiLateBindings.EditorUtility.SetDirty(unityObj); } }); } if (callbacks != null) { callbacks.OnAfterSerialize(); } return(success); }
protected override object CreateInstance() { return(InspectedType.Get(typeof(TEdited)).CreateInstance()); }
public ReflectedPropertyEditor(InspectedType metadata) { this._metadata = metadata; }
public static Dictionary <ObjectDataPath[], object> Create(List <ObjectDataPath> toUs, object obj, HashSet <object> seenObjects) { /* * Debug.Log(string.Join(", ", toUs.Select(t => { * if (t.byProperty == null) return ""; * return t.byProperty.Name; * }).ToArray())); * Debug.Log("seenObjects.Count = " + seenObjects.Count); * Debug.Log("seenObjects.Contains " + obj + " = " + seenObjects.Contains(obj)); */ Dictionary <ObjectDataPath[], object> thisLevel = AllocateDict(); if (seenObjects.Add(obj) == false) { return(thisLevel); } // Write the type. thisLevel.Add(CreateNavigation(toUs, new ObjectDataPath(toUs.ToArray())), obj.GetType()); List <InspectedProperty> properties = InspectedType.Get(obj.GetType()).GetProperties(InspectedMemberFilters.InspectableMembers); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; object valueForProperty = property.Read(obj); if (IsPrimitiveValue(valueForProperty)) { thisLevel.Add(CreateNavigation(toUs, new ObjectDataPath(property)), valueForProperty); continue; } if (InspectedType.Get(property.StorageType).IsCollection) { if (valueForProperty is IList) { var listForProperty = (IList)valueForProperty; for (int j = 0; j < listForProperty.Count; ++j) { object listElement = listForProperty[j]; if (IsPrimitiveValue(listElement)) { thisLevel.Add(CreateNavigation(toUs, new ObjectDataPath(property, j)), listElement); continue; } var listChildValues = CreateWithPath(toUs, new ObjectDataPath(property, j), listElement, seenObjects); foreach (var entry in listChildValues) { thisLevel.Add(entry.Key, entry.Value); } } } else if (valueForProperty is IDictionary) { var dictForProperty = (IDictionary)valueForProperty; IDictionaryEnumerator enumerator = dictForProperty.GetEnumerator(); while (enumerator.MoveNext()) { object key = enumerator.Key; object value = enumerator.Value; if (value == null || value.GetType().IsPrimitive || value is string) { thisLevel.Add(CreateNavigation(toUs, new ObjectDataPath(property, key)), value); } else { toUs.Add(new ObjectDataPath(property, key)); var dictChildValues = Create(toUs, value, seenObjects); toUs.RemoveAt(toUs.Count - 1); foreach (var entry in dictChildValues) { thisLevel.Add(entry.Key, entry.Value); } } } } else { Debug.LogError("Please file a bug (with an example) requesting multiedit support for " + valueForProperty.GetType().CSharpName()); } continue; } // Navigate children. var childValues = CreateWithPath(toUs, new ObjectDataPath(property), valueForProperty, seenObjects); foreach (var entry in childValues) { thisLevel.Add(entry.Key, entry.Value); } } return(thisLevel); }
public NullablePropertyEditor(Type elementType) { _elementType = InspectedType.Get(elementType); }
/// <summary> /// Serializes the current state of the given object. /// </summary> /// <typeparam name="TSerializer">The type of serializer to use for the serialization /// process.</typeparam> /// <param name="obj">The object that should be serialized.</param> /// <returns>True if serialization was entirely successful, false if something bad happened along the way.</returns> public static bool SaveState <TSerializer>(ISerializedObject obj) where TSerializer : BaseSerializer { bool success = true; // short-circuit for null serializer if (typeof(TSerializer) == typeof(NullSerializer)) { return(success); } var callbacks = obj as ISerializationCallbacks; if (callbacks != null) { callbacks.OnBeforeSerialize(); } // fetch the selected serializer var serializer = fiSingletons.Get <TSerializer>(); // setup the serialization operator var serializationOperator = fiSingletons.Get <ListSerializationOperator>(); serializationOperator.SerializedObjects = new List <UnityObject>(); // get the properties that we will be serializing var properties = InspectedType.Get(obj.GetType()).GetProperties(InspectedMemberFilters.FullInspectorSerializedProperties); var serializedKeys = new List <string>(); var serializedValues = new List <string>(); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; object currentValue = property.Read(obj); try { if (currentValue == null) { serializedKeys.Add(property.Name); serializedValues.Add(null); } else { var serializedState = serializer.Serialize(property.MemberInfo, currentValue, serializationOperator); serializedKeys.Add(property.Name); serializedValues.Add(serializedState); } } catch (Exception e) { success = false; Debug.LogError("Exception caught when serializing property <" + property.Name + "> in <" + obj + "> with value " + currentValue + "\n" + e); } } // Write the updated data out to the object. // Note that we only write data out to the object if our serialized state has // changed. Unity will blindly rewrite the data on disk which will cause some // source control systems to check-out the files. If we are just updating // the content to the same content, we do not want to cause an accidental // checkout. if (AreListsDifferent(obj.SerializedStateKeys, serializedKeys)) { obj.SerializedStateKeys = serializedKeys; } if (AreListsDifferent(obj.SerializedStateValues, serializedValues)) { obj.SerializedStateValues = serializedValues; } if (AreListsDifferent(obj.SerializedObjectReferences, serializationOperator.SerializedObjects)) { obj.SerializedObjectReferences = serializationOperator.SerializedObjects; } // Calling SetDirty seems cause prefab instances to have prefab differences after a script // reload, so we only call SetDirty on ScriptableObjects (it's only really necessary for those as well) if (obj is ScriptableObject) { fiLateBindings.EditorUtility.SetDirty((ScriptableObject)obj); } if (callbacks != null) { callbacks.OnAfterSerialize(); } fiEditorSerializationManager.MarkSerialized(obj); return(success); }
/// <summary> /// Serializes the current state of the given object. /// </summary> /// <typeparam name="TSerializer">The type of serializer to use for the serialization /// process.</typeparam> /// <param name="obj">The object that should be serialized.</param> /// <returns>True if serialization was entirely successful, false if something bad happened along the way.</returns> public static bool SaveState <TSerializer>(ISerializedObject obj) where TSerializer : BaseSerializer { bool success = true; var callbacks = obj as ISerializationCallbacks; if (callbacks != null) { callbacks.OnBeforeSerialize(); } // fetch the selected serializer var serializer = fiSingletons.Get <TSerializer>(); // setup the serialization operator var serializationOperator = fiSingletons.Get <ListSerializationOperator>(); serializationOperator.SerializedObjects = new List <UnityObject>(); // get the properties that we will be serializing var serializedKeys = new List <string>(); var serializedValues = new List <string>(); // PERF: Calling InspectedType().GetProperties() is extremely expensive. If we're not in the editor, then we can avoid making // that call because the only time we serialize an object is if it has existing FS data. If it has FS data, then that data // stores the set of properties which are serialized, so we can just hijack that information when doing the serialization to // determine which properties to serialize. if (fiUtility.IsEditor || obj.SerializedStateKeys == null || obj.SerializedStateKeys.Count == 0) { var properties = InspectedType.Get(obj.GetType()).GetProperties(InspectedMemberFilters.FullInspectorSerializedProperties); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; string serializedValue; if (SaveStateForProperty(obj, property, serializer, serializationOperator, out serializedValue, ref success)) { serializedKeys.Add(property.Name); serializedValues.Add(serializedValue); } } } else { var inspectedType = InspectedType.Get(obj.GetType()); for (int i = 0; i < obj.SerializedStateKeys.Count; ++i) { InspectedProperty property = inspectedType.GetPropertyByName(obj.SerializedStateKeys[i]) ?? inspectedType.GetPropertyByFormerlySerializedName(obj.SerializedStateKeys[i]); if (property == null) { continue; } string serializedValue; if (SaveStateForProperty(obj, property, serializer, serializationOperator, out serializedValue, ref success)) { serializedKeys.Add(property.Name); serializedValues.Add(serializedValue); } } } // Write the updated data out to the object. // Note that we only write data out to the object if our serialized state has // changed. Unity will blindly rewrite the data on disk which will cause some // source control systems to check-out the files. If we are just updating // the content to the same content, we do not want to cause an accidental // checkout. if (AreListsDifferent(obj.SerializedStateKeys, serializedKeys)) { obj.SerializedStateKeys = serializedKeys; } if (AreListsDifferent(obj.SerializedStateValues, serializedValues)) { obj.SerializedStateValues = serializedValues; } if (AreListsDifferent(obj.SerializedObjectReferences, serializationOperator.SerializedObjects)) { obj.SerializedObjectReferences = serializationOperator.SerializedObjects; } // Calling SetDirty seems cause prefab instances to have prefab differences after a script // reload, so we only call SetDirty on ScriptableObjects (it's only really necessary for those as well) if (obj is ScriptableObject) { fiLateBindings.EditorUtility.SetDirty((ScriptableObject)obj); } if (callbacks != null) { callbacks.OnAfterSerialize(); } return(success); }
void OnGUI() { // Frame rate tracking if (Event.current.type == EventType.Repaint) { AnimationHelper.UpdateTime(); } current = this; // Make sure we have a valid set of assemblies if (assemblies == null || assemblies.Count == 0) { ConstructAssembliesAndTypes(); } Rect windowRect = position; Type[] inspectedTypes = null; object[] inspectedContexts = null; GUILayout.Space(9); inspectedType = SidekickUtility.EnumToolbar(inspectedType, "LargeButton");//, GUILayout.Width(windowRect.width - 60)); if (inspectedType == InspectedType.Selection) { object selectedObject = ActiveSelection; if (selectedObject == null) { GUILayout.Space(windowRect.height / 2 - 40); GUIStyle style = new GUIStyle(GUI.skin.label); style.alignment = TextAnchor.MiddleCenter; GUILayout.Label("No object selected", style); return; } if (selectedObject is GameObject) { List <object> components = ((GameObject)selectedObject).GetComponents <Component>().Cast <object>().ToList(); components.RemoveAll(item => item == null); components.Insert(0, selectedObject); inspectedContexts = components.ToArray(); } else { inspectedContexts = new object[] { selectedObject }; } inspectedTypes = inspectedContexts.Select(x => x.GetType()).ToArray(); } else if (inspectedType == InspectedType.AssemblyClass) { int newSelectedAssemblyIndex = EditorGUILayout.Popup(selectedAssemblyIndex, assemblyNames); if (newSelectedAssemblyIndex != selectedAssemblyIndex) { selectedTypeIndex = 0; selectedAssemblyIndex = newSelectedAssemblyIndex; } Assembly activeAssembly = assemblies[selectedAssemblyIndex]; List <Type> types = assemblyTypes[activeAssembly]; string[] typeNames = new string[types.Count]; for (int i = 0; i < types.Count; i++) { typeNames[i] = types[i].FullName; } selectedTypeIndex = EditorGUILayout.Popup(selectedTypeIndex, typeNames); inspectedTypes = new Type[] { assemblyTypes[activeAssembly][selectedTypeIndex] }; inspectedContexts = new Type[] { null }; } else if (inspectedType == InspectedType.Remote) { } else { throw new NotImplementedException("Unhandled InspectedType"); } GUILayout.Space(5); EditorGUILayout.BeginHorizontal(); GUIStyle searchStyle = GUI.skin.FindStyle("ToolbarSeachTextField"); GUIStyle cancelStyle = GUI.skin.FindStyle("ToolbarSeachCancelButton"); GUIStyle noCancelStyle = GUI.skin.FindStyle("ToolbarSeachCancelButtonEmpty"); GUILayout.Space(10); settings.SearchTerm = EditorGUILayout.TextField(settings.SearchTerm, searchStyle); if (!string.IsNullOrEmpty(settings.SearchTerm)) { if (GUILayout.Button("", cancelStyle)) { settings.SearchTerm = ""; GUIUtility.hotControl = 0; EditorGUIUtility.editingTextField = false; } } else { GUILayout.Button("", noCancelStyle); } GUILayout.Space(10); EditorGUILayout.EndHorizontal(); GUILayout.Space(5); mode = SidekickUtility.EnumToolbar(mode); // mode = SabreGUILayout.DrawEnumGrid(mode); GUILayout.Space(5); scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); for (int i = 0; i < inspectedTypes.Length; i++) { Type type = inspectedTypes[i]; if (!typesHidden.Any(row => row.Key == type))// ContainsKey(component)) { typesHidden.Add(new KeyValuePair <Type, bool>(type, false)); } int index = typesHidden.FindIndex(row => row.Key == type); GUIStyle style = new GUIStyle(EditorStyles.foldout); style.fontStyle = FontStyle.Bold; // Texture2D icon = AssetPreview.GetMiniTypeThumbnail(type); GUIContent objectContent = EditorGUIUtility.ObjectContent(inspectedContexts[i] as UnityEngine.Object, type); Texture2D icon = objectContent.image as Texture2D; GUIContent content = new GUIContent(type.Name, icon); bool newValue = !EditorGUILayout.Foldout(!typesHidden[index].Value, content, style); if (newValue != typesHidden[index].Value) { typesHidden[index] = new KeyValuePair <Type, bool>(type, newValue); } if (!typesHidden[index].Value) { EditorGUI.indentLevel = 1; BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; if (!settings.IncludeInherited) { bindingFlags |= BindingFlags.DeclaredOnly; } FieldInfo[] fields = type.GetFields(bindingFlags); PropertyInfo[] properties = type.GetProperties(bindingFlags); MethodInfo[] methods = type.GetMethods(bindingFlags); // Hide methods and backing fields that have been generated for properties if (settings.HideAutoGenerated) { List <MethodInfo> methodList = new List <MethodInfo>(methods.Length); for (int j = 0; j < methods.Length; j++) { if (!TypeUtility.IsPropertyMethod(methods[j], type)) { methodList.Add(methods[j]); } } methods = methodList.ToArray(); List <FieldInfo> fieldList = new List <FieldInfo>(fields.Length); for (int j = 0; j < fields.Length; j++) { if (!TypeUtility.IsBackingField(fields[j], type)) { fieldList.Add(fields[j]); } } fields = fieldList.ToArray(); } FieldInfo[] events = type.GetFields(bindingFlags); if (mode == InspectorMode.Fields) { fieldPane.DrawFields(inspectedTypes[i], inspectedContexts[i], fields); } else if (mode == InspectorMode.Props) { propertyPane.DrawProperties(inspectedTypes[i], inspectedContexts[i], properties); } else if (mode == InspectorMode.Methods) { methodPane.DrawMethods(inspectedTypes[i], inspectedContexts[i], methods); } else if (mode == InspectorMode.Events) { eventPane.DrawEvents(inspectedTypes[i], inspectedContexts[i], events); } else if (mode == InspectorMode.Misc) { utilityPane.Draw(inspectedTypes[i], inspectedContexts[i]); } EditorGUI.indentLevel = 0; } Rect rect = GUILayoutUtility.GetRect(new GUIContent(), GUI.skin.label, GUILayout.ExpandWidth(true), GUILayout.Height(1)); rect.xMin -= 10; rect.xMax += 10; GUI.color = new Color(0.5f, 0.5f, 0.5f); GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture); GUI.color = Color.white; } EditorGUILayout.EndScrollView(); if (mode == InspectorMode.Methods) { methodPane.PostDraw(); } settings.RotationsAsEuler = EditorGUILayout.Toggle("Rotations as euler", settings.RotationsAsEuler); settings.IncludeInherited = EditorGUILayout.Toggle("Include inherited", settings.IncludeInherited); settings.HideAutoGenerated = EditorGUILayout.Toggle("Hide auto-generated", settings.HideAutoGenerated); settings.TreatEnumsAsInts = EditorGUILayout.Toggle("Enums as ints", settings.TreatEnumsAsInts); EditorGUILayout.BeginHorizontal(); GUI.enabled = (backStack.Count > 0); if (GUILayout.Button("<-") || (Event.current.type == EventType.MouseDown && Event.current.button == 3) || (Event.current.type == EventType.KeyDown && SidekickUtility.EventsMatch(Event.current, Event.KeyboardEvent("Backspace"), false, true))) { object backStackLast = backStack.Last(); backStack.RemoveAt(backStack.Count - 1); forwardStack.Add(ActiveSelection); SetSelection(backStackLast, false); } GUI.enabled = (forwardStack.Count > 0); if (GUILayout.Button("->") || (Event.current.type == EventType.MouseDown && Event.current.button == 4) || (Event.current.type == EventType.KeyDown && SidekickUtility.EventsMatch(Event.current, Event.KeyboardEvent("#Backspace"), false, true))) { object forwardStackLast = forwardStack.Last(); forwardStack.RemoveAt(forwardStack.Count - 1); backStack.Add(ActiveSelection); SetSelection(forwardStackLast, false); } GUI.enabled = true; if (GUILayout.Button("Pin")) { selectionOverride = ActiveSelection; } EditorGUILayout.EndHorizontal(); // test += currentFrameDelta; // Color color = Color.Lerp(Color.white, Color.red, Mathf.PingPong(test, 1f)); // GUI.backgroundColor = color; // GUILayout.Button(Mathf.PingPong(test, 1f).ToString());//test.ToString()); // if(AnimationHelper.AnimationActive) { // Cause repaint on next frame Repaint(); if (Event.current.type == EventType.Repaint) { // AnimationHelper.ClearAnimationActive(); } } }
public ReflectedPropertyEditor(InspectedType metadata) { _metadata = metadata; }
public void Write(object context, object value) { if (byType != null) { if (value != s_RemoveObject) { value = InspectedType.Get((Type)value).CreateInstance(); } byType[byType.Length - 1].Write(context, value); return; } // The property was potentially found on a different type. We need to // update it to associate with this type. It's very possible the // property will not even apply to context, in which case Write // becomes a no-op. InspectedProperty propertyToUse = byProperty; if (byProperty.MemberInfo.DeclaringType != context.GetType()) { var childProp = InspectedType.Get(context.GetType()).GetPropertyByName(byProperty.Name); if (childProp != null) { propertyToUse = childProp; } else { return; } } if (byListIndex >= 0) { var read = propertyToUse.Read(context); var list = (IList)read; var elementType = InspectedType.Get(propertyToUse.StorageType).ElementType; if (value == s_RemoveObject) { fiListUtility.RemoveAt(ref list, elementType, byListIndex); } else { while (byListIndex >= list.Count) { fiListUtility.Add(ref list, elementType); } list[byListIndex] = value; } // Changing list will not update the actual array reference, so // we have to write back to the stored object. if (list is Array) { propertyToUse.Write(context, list); } return; } if (byDictKey != null) { var read = propertyToUse.Read(context); var dict = (IDictionary)read; // TODO: Have a separate Write/Remove command, since you might // want to set a dict field to null. if (value == s_RemoveObject) { dict.Remove(byDictKey); } else { dict[byDictKey] = value; } return; } if (value != s_RemoveObject) { propertyToUse.Write(context, value); } else { propertyToUse.Write(context, null); } }
public object CreateInstance() { return(InspectedType.Get(byProperty.StorageType).CreateInstance()); }
public static RuntimeTypeModel CreateModel() { var model = TypeModel.Create(); // We want protobuf-net to serialize default values. Sometimes, protobuf-net will skip // serialization when it really shouldn't. // // An example is a nullable struct; the nullable struct can contain a value, but if // that value is the default one then protobuf-net will skip serialization, resulting // in a null nullable type after deserialization. model.UseImplicitZeroDefaults = false; // custom model workers foreach (IProtoModelWorker worker in fiRuntimeReflectionUtility.GetAssemblyInstances <IProtoModelWorker>()) { worker.Work(model); } // regular old [ProtoContract] types foreach (Type contract in GetContracts(model)) { if (contract.Resolve().IsVisible == false) { Throw("A ProtoContract type needs to have public visibility for contract={0}", contract); } model.Add(RunSanityCheck(contract), true); } // Fields and properties on UnityObject derived types, such as BaseBehavior, are not // annotated with serialization annotations. This means that for protobuf-net, if a // BaseBehavior contains a Dictionary{string,string} field, then that specific generic // instantiation may not be discovered, as the field does not serve as an anchor. // // In this loop, we go through all UnityObject derived types and ensure that every // serialized property is in the RuntimeTypeModel. foreach (var behaviorType in fiRuntimeReflectionUtility.GetUnityObjectTypes()) { // We only want UnityObject types are serializable by ProtoBufNet // TODO: support custom base classes if (typeof(BaseBehavior <ProtoBufNetSerializer>).Resolve().IsAssignableFrom(behaviorType.Resolve()) == false) { continue; } var serializedProperties = InspectedType.Get(behaviorType).GetProperties(InspectedMemberFilters.FullInspectorSerializedProperties); foreach (InspectedProperty property in serializedProperties) { // If the property is generic and the model currently doesn't contain it, make // sure we add it to the model. if (property.StorageType.Resolve().IsGenericType&& ContainsType(model, property.StorageType) == false) { model.Add(property.StorageType, true); } } } return(model); }
public void OnGUI() { try { EditorGUIUtility.hierarchyMode = true; Type updatedType = _inspectedType; GUILayout.Label("Static Inspector", EditorStyles.boldLabel); { var label = new GUIContent("Inspected Type"); var typeEditor = PropertyEditor.Get(typeof(Type), null); updatedType = typeEditor.FirstEditor.EditWithGUILayout(label, _inspectedType, Metadata.Enter("TypeSelector")); } fiEditorGUILayout.Splitter(2); if (_inspectedType != null) { _inspectorScrollPosition = EditorGUILayout.BeginScrollView(_inspectorScrollPosition); var inspectedType = InspectedType.Get(_inspectedType); foreach (InspectedProperty staticProperty in inspectedType.GetProperties(InspectedMemberFilters.StaticInspectableMembers)) { var editorChain = PropertyEditor.Get(staticProperty.StorageType, staticProperty.MemberInfo); IPropertyEditor editor = editorChain.FirstEditor; GUIContent label = new GUIContent(staticProperty.Name); object currentValue = staticProperty.Read(null); EditorGUILayout.BeginHorizontal(); EditorGUILayout.GetControlRect(GUILayout.Width(8)); EditorGUILayout.BeginVertical(); GUI.enabled = staticProperty.CanWrite; object updatedValue = editor.EditWithGUILayout(label, currentValue, Metadata.Enter(staticProperty.Name)); if (staticProperty.CanWrite) { staticProperty.Write(null, updatedValue); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndScrollView(); } // For some reason, the type selection popup window cannot force the rest of the // Unity GUI to redraw. We do it here instead -- this removes any delay after // selecting the type in the popup window and the type actually being displayed. if (fiEditorUtility.ShouldInspectorRedraw.Enabled) { Repaint(); } if (_inspectedType != updatedType) { _inspectedType = updatedType; Repaint(); } EditorGUIUtility.hierarchyMode = false; } catch (ExitGUIException) { } catch (Exception e) { Debug.LogError(e); } }
public NullablePropertyEditor(Type type) { this._elementType = InspectedType.Get(type.GetGenericArguments()[0]); }