Exemple #1
0
    private static ExpressionFieldAttribute GetExpressionFieldAttribute(Type expressionContainingType, SerializedProperty expressionProperty)
    {
        if (!_expressionPropertyAttributesByExpressionType.ContainsKey(expressionContainingType))
        {
            _expressionPropertyAttributesByExpressionType.Add(expressionContainingType, new Dictionary <string, ExpressionFieldAttribute>());
        }

        var propertyCache = _expressionPropertyAttributesByExpressionType[expressionContainingType];

        if (!propertyCache.ContainsKey(expressionProperty.name))
        {
            FieldInfo fieldInfo = expressionContainingType.GetField(expressionProperty.name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
            ExpressionFieldAttribute fieldAttribute = null;
            if (fieldInfo != null)
            {
                ExpressionFieldAttribute[] typeAttributes = (ExpressionFieldAttribute[])fieldInfo.GetCustomAttributes(typeof(ExpressionFieldAttribute), false);
                if (typeAttributes.Length != 0)
                {
                    fieldAttribute = typeAttributes[0];
                }
            }
            propertyCache.Add(expressionProperty.name, fieldAttribute);
        }

        return(propertyCache[expressionProperty.name]);
    }
        static LambdaExpression GetExpansion(MemberInfo mi)
        {
            ExpressionFieldAttribute efa = mi.GetCustomAttribute <ExpressionFieldAttribute>();

            if (efa == null)
            {
                return(null);
            }

            if (efa.Name == "auto")
            {
                throw new InvalidOperationException($"The {nameof(ExpressionFieldAttribute)} for {mi.DeclaringType.TypeName()}.{mi.MemberName()} has the default value 'auto'.\r\nMaybe Signum.MSBuildTask is not running in assemby {mi.DeclaringType.Assembly.GetName().Name}?");
            }

            Type      type = mi.DeclaringType;
            FieldInfo fi   = type.GetField(efa.Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            if (fi == null)
            {
                throw new InvalidOperationException("Expression field '{0}' not found on '{1}'".FormatWith(efa.Name, type.TypeName()));
            }

            var obj = fi.GetValue(null);

            if (obj == null)
            {
                throw new InvalidOperationException("Expression field '{0}' is null".FormatWith(efa.Name));
            }

            var result = obj as LambdaExpression;

            if (result == null)
            {
                throw new InvalidOperationException("Expression field '{0}' does not contain a lambda expression".FormatWith(efa.Name, type.TypeName()));
            }

            return(result);
        }
Exemple #3
0
    public static void DrawExpressionSelector(SerializedProperty expressionProperty, Type expressionContainingType, Dictionary <string, Variable> variables)
    {
        ExpressionFieldAttribute fieldAttribute = GetExpressionFieldAttribute(expressionContainingType, expressionProperty);

        // Defaults for display name and required type if attribute isn't present.
        Type   requiredExpressionValueType = fieldAttribute != null ? fieldAttribute.ExpressionType : typeof(object);
        string displayName = fieldAttribute != null ? fieldAttribute.DisplayName : expressionProperty.name;

        if (requiredExpressionValueType == typeof(Variable))
        {
            // Special case. Show all variables:
            UnityEngine.Object propertyValue = expressionProperty.objectReferenceValue;
            if (propertyValue == null || !(propertyValue is VariableLiteralExpression))
            {
                expressionProperty.objectReferenceValue = ScriptableObject.CreateInstance <VariableLiteralExpression>();
            }
            VariableLiteralExpression variableExpression = (VariableLiteralExpression)expressionProperty.objectReferenceValue;

            GUILayout.BeginHorizontal();
            GUILayout.Label(GetFriendlyPropertyDisplayName(expressionProperty), GUILayout.ExpandWidth(false));
            GUILayout.FlexibleSpace();
            Variable variableValue = VariableSelector(variableExpression.Value as Variable, typeof(object), variables, false);
            GUILayout.EndHorizontal();
            variableExpression.VariableValue = variableValue;
            return;
        }

        // Get collection of all expression types in the project.
        // Filter the expression types returned to those that match the field required type.

        Dictionary <string, Type> expressionTypes = GetValidExpressionTypes(requiredExpressionValueType);

        // Get a string array of expression type names to display
        string[] typeArray = expressionTypes.Keys.ToArray();

        // Find the current value of the expression property.
        UnityEngine.Object currentValue = expressionProperty.objectReferenceValue;

        // Find the index of the selection in the typeArray to show the correct type in the drop down
        string currentSelection      = currentValue == null ? "-" : currentValue.GetType().Name;
        int    currentSelectionIndex = Array.IndexOf(typeArray, currentSelection);

        // Show the drop down selector
        GUILayout.BeginHorizontal();
        GUILayout.Label(displayName, GUILayout.ExpandWidth(false));
        GUILayout.FlexibleSpace();
        int newSelectionIndex = EditorGUILayout.Popup(currentSelectionIndex, expressionTypes.Keys.ToArray());


        // If the new index isn't what we had before, find the new expression type in the dictionary by type name and assign a new instance of it.
        if (currentSelectionIndex != newSelectionIndex)
        {
            Type newType = expressionTypes[typeArray[newSelectionIndex]];
            if (newType != null)
            {
                expressionProperty.objectReferenceValue = ScriptableObject.CreateInstance(newType);
                expressionProperty.serializedObject.ApplyModifiedProperties();
                currentValue = expressionProperty.objectReferenceValue;
            }
        }

        // Now show the fields of the assigned expression object (if not null)
        if (currentValue != null)
        {
            SerializedObject serializedObject = new SerializedObject(currentValue);
            // If it's a VariableExpression, then we need to show the custom VariableSelector.
            if (currentValue.GetType() == typeof(VariableExpression))
            {
                DrawVariableSelector(serializedObject, requiredExpressionValueType, variables);
            }
            else
            {
                // Otherwise, just show the properties like normal.
                SerializedProperty property = serializedObject.GetIterator();
                property.NextVisible(true);
                while (property.NextVisible(false))
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label(GetFriendlyPropertyDisplayName(property));
                    EditorGUILayout.PropertyField(property, GUIContent.none, true);
                    serializedObject.ApplyModifiedProperties();
                    GUILayout.EndHorizontal();
                }
            }
        }
        GUILayout.EndHorizontal();
    }