コード例 #1
0
        /// <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());
        }
コード例 #2
0
    //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();
    }
コード例 #3
0
        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);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        /// <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();
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        /// <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();
                }
            }
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
 protected override object CreateInstance()
 {
     return(InspectedType.Get(typeof(TEdited)).CreateInstance());
 }
コード例 #10
0
 public ReflectedPropertyEditor(InspectedType metadata)
 {
     this._metadata = metadata;
 }
コード例 #11
0
ファイル: SavedObject.cs プロジェクト: smbss1/fullinspector
        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);
        }
コード例 #12
0
 public NullablePropertyEditor(Type elementType)
 {
     _elementType = InspectedType.Get(elementType);
 }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
        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();
                }
            }
        }
コード例 #16
0
 public ReflectedPropertyEditor(InspectedType metadata)
 {
     _metadata = metadata;
 }
コード例 #17
0
        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);
            }
        }
コード例 #18
0
 public object CreateInstance()
 {
     return(InspectedType.Get(byProperty.StorageType).CreateInstance());
 }
コード例 #19
0
ファイル: TypeModelCreator.cs プロジェクト: Mhyshka/FFEngine
        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);
        }
コード例 #20
0
 public NullablePropertyEditor(Type elementType)
 {
     _elementType = InspectedType.Get(elementType);
 }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
 public NullablePropertyEditor(Type type)
 {
     this._elementType = InspectedType.Get(type.GetGenericArguments()[0]);
 }