Exemple #1
0
 /// <summary>
 /// Initializes the <see cref="BaseEditorUtility"/> class.
 /// </summary>
 static BaseEditorUtility()
 {
     foreach (System.Type type in ReflectionX.AllTypes)
     {
         if (!type.IsAbstract && typeof(BaseEditor).IsAssignableFrom(type))
         {
             MethodInfo initializeMethod = type.GetMethod("InitializeClass", ReflectionX.staticBindingFlags);
             if (initializeMethod != null)
             {
                 initializeMethod.Invoke(null, null);
             }
             PropertyInfo featureGroupProp = type.GetProperty("FeatureGroup", ReflectionX.staticBindingFlags);
             if (featureGroupProp == null)
             {
                 continue;
             }
             string featureGroup = featureGroupProp.GetValue(null, null) as string;
             if (string.IsNullOrEmpty(featureGroup))
             {
                 continue;
             }
             MethodInfo prefMenuMethod =
                 type.GetMethod("DisplayHandlePreferences", ReflectionX.staticBindingFlags);
             if (prefMenuMethod == null || prefMenuMethod.DeclaringType != type)
             {
                 continue;
             }
             EditorPreferenceMenu.AddPreferenceMenuItem(featureGroup, prefMenuMethod);
         }
     }
 }
Exemple #2
0
 /// <summary>
 /// Initializes the <see cref="BaseEditorUtility"/> class.
 /// </summary>
 static BaseEditorUtility()
 {
     foreach (System.Type type in ReflectionX.AllTypes)
     {
         if (!type.IsAbstract && typeof(BaseEditor).IsAssignableFrom(type))
         {
             MethodInfo initializeMethod = type.GetStaticMethod("InitializeClass");
             if (initializeMethod != null)
             {
                 initializeMethod.Invoke(null, null);
             }
             PropertyInfo featureGroupProp = type.GetStaticProperty("ProductCategory");
             if (featureGroupProp == null)
             {
                 continue;
             }
             AssetStoreProduct product = (AssetStoreProduct)featureGroupProp.GetValue(null, null);
             if (product == AssetStoreProduct.None)
             {
                 continue;
             }
             MethodInfo prefMenuMethod = type.GetStaticMethod("DisplayHandlePreferences");
             if (prefMenuMethod == null || prefMenuMethod.DeclaringType != type)
             {
                 continue;
             }
             EditorPreferenceMenu.AddPreferenceMenuItem(product, prefMenuMethod);
         }
     }
 }
Exemple #3
0
        /// <summary>
        /// Initializes the <see cref="Candlelight.PropertyBackingFieldDrawer"/> class.
        /// </summary>
        static PropertyBackingFieldDrawer()
        {
            // add preference menu item
            EditorPreferenceMenu.AddPreferenceMenuItem(
                "Property Backing Field", () => EditorGUILayout.LabelField("Thanks for your bug reports!")
                );
            //register callbacks with UnityEditor.Undo
            Undo.postprocessModifications += OnPerformUndoableAction;
            Undo.undoRedoPerformed        += OnUndoRedo;
            // get all types incompatible with this feature
            HashSet <System.Type> typesThatCannotBeBackingFields = new HashSet <System.Type>(
                ObjectX.AllTypes.Where(
                    t =>
                    (t.IsClass || (t.IsValueType && !t.IsEnum && !t.IsPrimitive)) &&
                    t.GetCustomAttributes <System.SerializableAttribute>().Count() > 0 &&
                    !typeof(IPropertyBackingFieldCompatible).IsAssignableFrom(t)
                    )
                );

            typesThatCannotBeBackingFields.Remove(typeof(string));
            // collect T[] and List<T> for each incompatible type
            HashSet <System.Type> sequenceTypesThatCannotBeBackingFields = new HashSet <System.Type>();

            foreach (System.Type incompatibleType in typesThatCannotBeBackingFields)
            {
                sequenceTypesThatCannotBeBackingFields.Add(incompatibleType.MakeArrayType());
                sequenceTypesThatCannotBeBackingFields.Add(
                    typeof(List <>).MakeGenericType(new System.Type[] { incompatibleType })
                    );
            }
            // collect any fields that will cause problems with types that cannot be marked as backing fields
            Dictionary <System.Type, List <FieldInfo> > problematicFields = new Dictionary <System.Type, List <FieldInfo> >();

            // examine all fields on the scripted types to find any problematic usages
            foreach (System.Type providerType in ObjectX.AllTypes)
            {
                foreach (FieldInfo field in providerType.GetFields(ObjectX.instanceBindingFlags))
                {
                    System.Type typeToValidate = field.FieldType;
                    // skip the field if it is known to be compatible
                    if (
                        !typesThatCannotBeBackingFields.Contains(typeToValidate) &&
                        !sequenceTypesThatCannotBeBackingFields.Contains(typeToValidate)
                        )
                    {
                        continue;
                    }
                    // skip the field if it is a built-in Unity type
                    if (ObjectX.UnityRuntimeAssemblies.Contains(typeToValidate.Assembly))
                    {
                        continue;
                    }
                    // skip the field if it is not serialized
                    if (field.IsPrivate && field.GetCustomAttributes <SerializeField>().Count() == 0)
                    {
                        continue;
                    }
                    // skip the field if it is not designated as a backing field
                    if (field.GetCustomAttributes <PropertyBackingFieldAttribute>().Count() == 0)
                    {
                        continue;
                    }
                    // add the type to the problem table
                    if (typeToValidate.IsArray)
                    {
                        typeToValidate = typeToValidate.GetElementType();
                    }
                    else if (typeToValidate.IsGenericType)
                    {
                        typeToValidate = typeToValidate.GetGenericArguments()[0];
                    }
                    if (!problematicFields.ContainsKey(typeToValidate))
                    {
                        problematicFields.Add(typeToValidate, new List <FieldInfo>());
                    }
                    // add the field to the type's list of problematic usages
                    problematicFields[typeToValidate].Add(field);
                }
            }
            // display messages for any problems
            foreach (KeyValuePair <System.Type, List <FieldInfo> > problematicType in problematicFields)
            {
                Debug.LogError(
                    string.Format(
                        "<b>{0}</b> must implement <b>{1}<{0}></b>, because it is marked with <b>{2}</b> on the following fields:\n{3}",
                        problematicType.Key,
                        typeof(IPropertyBackingFieldCompatible).FullName,
                        typeof(PropertyBackingFieldAttribute).FullName,
                        string.Join(
                            "\n",
                            (
                                from field in problematicType.Value
                                select string.Format(
                                    "    - <i>{0}.{1}</i>",
                                    field.DeclaringType, field.Name
                                    )
                            ).ToArray()
                            )
                        )
                    );
            }
        }