예제 #1
0
        private static bool GetPropertyTrackArchetype(Type valueType, out TrackArchetype archetype, out string name)
        {
            // Validate value type and pick the track archetype
            name = valueType.Name;
            if (BasicTypesTrackArchetypes.TryGetValue(valueType, out archetype))
            {
                // Basic type
                if (!BasicTypesNames.TryGetValue(valueType, out name))
                {
                    name = valueType.Name;
                }
            }
            else if (valueType.IsEnum)
            {
                // Enum
                archetype = KeyframesPropertyTrack.GetArchetype();
            }
            else if (valueType.IsValueType)
            {
                // Structure
                archetype = StructPropertyTrack.GetArchetype();
            }
            else if (typeof(FlaxEngine.Object).IsAssignableFrom(valueType))
            {
                // Flax object reference
                archetype = ObjectReferencePropertyTrack.GetArchetype();
            }
            else if (CanAnimateObjectType(valueType))
            {
                // Nested object
                archetype = ObjectPropertyTrack.GetArchetype();
            }
            else
            {
                // Not supported
                return(true);
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Adds the object events track options to menu.
        /// </summary>
        /// <param name="parentTrack">The parent track.</param>
        /// <param name="menu">The menu.</param>
        /// <param name="type">The object type.</param>
        /// <param name="memberCheck">The custom callback that can reject the members that should not be animated. Returns true if member is valid. Can be null to skip this feature.</param>
        /// <returns>The added options count.</returns>
        public static int AddEvents(Track parentTrack, ContextMenu.ContextMenu menu, Type type, Func <MemberInfo, bool> memberCheck = null)
        {
            int count = 0;

            menu.Tag = parentTrack;

            // TODO: implement editor-wide cache for animated properties per object type (add this in CodeEditingModule)
            var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);

            var sb = new StringBuilder();

            for (int i = 0; i < members.Length; i++)
            {
                var m = members[i] as MethodInfo;
                if (m == null)
                {
                    continue;
                }
                if (memberCheck != null && !memberCheck(m))
                {
                    continue;
                }

                // Skip properties getters/setters and events add/remove
                var mName = m.Name;
                if (mName.StartsWith("get_", StringComparison.Ordinal) ||
                    mName.StartsWith("set_", StringComparison.Ordinal) ||
                    mName.StartsWith("add_", StringComparison.Ordinal) ||
                    mName.StartsWith("remove_", StringComparison.Ordinal))
                {
                    continue;
                }

                // Allow to invoke only void functions with basic parameter types
                var parameters = m.GetParameters();
                if (m.ReturnType != typeof(void) ||
                    parameters.Length > 8 ||
                    m.IsGenericMethod ||
                    parameters.Any(IsEventParamInvalid))
                {
                    continue;
                }

                var attributes = m.GetCustomAttributes();

                // Check if has attribute to skip animating
                if (attributes.Any(x => x is NoAnimateAttribute))
                {
                    continue;
                }

                // Prevent from adding the same track twice
                if (parentTrack.SubTracks.Any(x => x is MemberTrack y && y.MemberName == m.Name))
                {
                    continue;
                }

                // Build function name for UI
                sb.Clear();
                sb.Append(mName);
                sb.Append('(');
                for (int j = 0; j < parameters.Length; j++)
                {
                    if (j != 0)
                    {
                        sb.Append(", ");
                    }
                    var p = parameters[j];
                    if (!BasicTypesNames.TryGetValue(p.ParameterType, out var pName))
                    {
                        pName = p.ParameterType.Name;
                    }
                    sb.Append(pName);
                    sb.Append(' ');
                    sb.Append(p.Name);
                }
                sb.Append(')');

                AddMemberTag tag;
                tag.Member    = m;
                tag.Archetype = EventTrack.GetArchetype();

                menu.AddButton(sb.ToString(), OnAddMemberTrack).Tag = tag;
                count++;
            }

            return(count);
        }