/// <summary>
        /// Return an array of all System types available to the runtime matching the WorldSystemFilterFlags. By default,
        /// all systems available to the runtime is returned.
        /// </summary>
        public static IReadOnlyList <Type> GetSystems(WorldSystemFilterFlags filterFlags = WorldSystemFilterFlags.All, WorldSystemFilterFlags requiredFlags = WorldSystemFilterFlags.Default)
        {
            Assertions.Assert.IsTrue(requiredFlags > 0, "Must use a 'requiredFlags' greater than 0. If you want to get all systems with any flag, pass a filterFlag of WorldSystemFilterFlags.All");
            LookupFlags lookupFlags = new LookupFlags()
            {
                OptionalFlags = filterFlags, RequiredFlags = requiredFlags
            };

            if (s_SystemFilterTypeMap.TryGetValue(lookupFlags, out var systemTypes))
            {
                return(systemTypes);
            }

#if !UNITY_DOTSRUNTIME
            var filteredSystemTypes = new List <Type>();
            foreach (var systemType in GetTypesDerivedFrom(typeof(ComponentSystemBase)))
            {
                if (FilterSystemType(systemType, lookupFlags))
                {
                    filteredSystemTypes.Add(systemType);
                }
            }

            foreach (var unmanagedSystemType in GetTypesDerivedFrom(typeof(ISystemBase)))
            {
                if (!unmanagedSystemType.IsValueType)
                {
                    continue;
                }

                if (FilterSystemType(unmanagedSystemType, lookupFlags))
                {
                    filteredSystemTypes.Add(unmanagedSystemType);
                }
            }

            s_SystemFilterTypeMap[lookupFlags] = filteredSystemTypes;
            return(filteredSystemTypes);
#else
            Assertions.Assert.IsTrue(s_Initialized, "The TypeManager must be initialized before the TypeManager can be used.");
            var filteredSystemTypes = new List <Type>();
            if (lookupFlags.OptionalFlags == WorldSystemFilterFlags.All)
            {
                filteredSystemTypes = s_SystemTypes;
            }
            else
            {
                for (int i = 0; i < s_SystemTypes.Count; ++i)
                {
                    if (!IsSystemDisabledForCreation(s_SystemTypes[i]) && (s_SystemFilterFlagsList[i] & lookupFlags.OptionalFlags) >= lookupFlags.RequiredFlags)
                    {
                        filteredSystemTypes.Add(s_SystemTypes[i]);
                    }
                }
            }

            s_SystemFilterTypeMap[lookupFlags] = filteredSystemTypes;
            return(filteredSystemTypes);
#endif
        }
Example #2
0
        /// <summary>
        /// Calculates a list of all systems filtered with WorldSystemFilterFlags, [DisableAutoCreation] etc.
        /// </summary>
        /// <param name="filterFlags"></param>
        /// <param name="requireExecuteAlways">Optionally require that [ExecuteAlways] is present on the system. This is used when creating edit mode worlds.</param>
        /// <returns>The list of filtered systems</returns>
        public static IReadOnlyList <Type> GetAllSystems(WorldSystemFilterFlags filterFlags, bool requireExecuteAlways = false)
        {
            if (s_SystemTypeCache == null)
            {
                s_SystemTypeCache = new Dictionary <SystemLookupParameters, List <Type> >();
            }
            var lookupParameters = new SystemLookupParameters
            {
                Flags = filterFlags,
                RequireExecuteAlways = requireExecuteAlways
            };

            if (s_SystemTypeCache.TryGetValue(lookupParameters, out var systemTypes))
            {
                return(systemTypes);
            }

            var filteredSystemTypes = new List <Type>();
            var allSystemTypes      = GetTypesDerivedFrom(typeof(ComponentSystemBase));

            foreach (var systemType in allSystemTypes)
            {
                if (FilterSystemType(systemType, filterFlags, requireExecuteAlways))
                {
                    filteredSystemTypes.Add(systemType);
                }
            }

            s_SystemTypeCache[lookupParameters] = filteredSystemTypes;
            return(filteredSystemTypes);
        }
Example #3
0
        /// <summary>
        /// Calculates a list of all systems filtered with WorldSystemFilterFlags, [DisableAutoCreation] etc.
        /// </summary>
        /// <param name="filterFlags"></param>
        /// <param name="requireExecuteAlways">Optionally require that [ExecuteAlways] is present on the system. This is used when creating edit mode worlds.</param>
        /// <returns>The list of filtered systems</returns>
        public static List <Type> GetAllSystems(WorldSystemFilterFlags filterFlags, bool requireExecuteAlways = false)
        {
            var filteredSystemTypes = new List <Type>();

            var allSystemTypes = GetTypesDerivedFrom(typeof(ComponentSystemBase));

            foreach (var systemType in allSystemTypes)
            {
                if (FilterSystemType(systemType, filterFlags, requireExecuteAlways))
                {
                    filteredSystemTypes.Add(systemType);
                }
            }

            return(filteredSystemTypes);
        }
Example #4
0
        int ValidateFilterFlags(WorldSystemFilterFlags expectedFilterFlags, WorldSystemFilterFlags requiredFlags = WorldSystemFilterFlags.Default)
        {
            Assert.IsTrue(expectedFilterFlags != WorldSystemFilterFlags.All);

            var filteredTypes = TypeManager.GetSystems(expectedFilterFlags, requiredFlags);

            foreach (var t in filteredTypes)
            {
                var actualFilterFlags = TypeManager.GetSystemFilterFlags(t);

                Assert.IsTrue((expectedFilterFlags & actualFilterFlags) != 0, $"Flags for system {t} do not match");
                Assert.GreaterOrEqual((int)actualFilterFlags, (int)requiredFlags, $"Actual Flags for system {t} should be greater than or equal to required flags");
            }

            return(filteredTypes.Count);
        }
        // Internal function used for tests
        internal static WorldSystemFilterFlags GetSystemFilterFlags(Type type)
        {
            WorldSystemFilterFlags systemFlags = WorldSystemFilterFlags.Default;

#if !NET_DOTS
            if (Attribute.IsDefined(type, typeof(WorldSystemFilterAttribute), true))
            {
                systemFlags = type.GetCustomAttribute <WorldSystemFilterAttribute>(true).FilterFlags;
            }

            if (Attribute.IsDefined(type, typeof(ExecuteAlways)))
            {
                // Until we formally deprecate ExecuteAlways, add in the Editor flag as this has the same meaning
                // When we deprecate uncomment the log error below
                //Debug.LogError($"{type} is decorated with {typeof(ExecuteAlways)}. Support for this attribute will be deprecated. Please use [WorldSystemFilter(WorldSystemFilterFlags.EditTime)] instead.");
                systemFlags |= WorldSystemFilterFlags.Editor;
            }
#else
            systemFlags = s_SystemFilterFlagsList[GetSystemTypeIndex(type)];
#endif
            return(systemFlags);
        }
Example #6
0
        static bool FilterSystemType(Type type, WorldSystemFilterFlags filterFlags, bool requireExecuteAlways)
        {
            // IMPORTANT: keep this logic in sync with SystemTypeGen.cs for DOTS Runtime

            // the entire assembly can be marked for no-auto-creation (test assemblies are good candidates for this)
            var disableAllAutoCreation  = Attribute.IsDefined(type.Assembly, typeof(DisableAutoCreationAttribute));
            var disableTypeAutoCreation = Attribute.IsDefined(type, typeof(DisableAutoCreationAttribute), false);

            // these types obviously cannot be instantiated
            if (type.IsAbstract || type.ContainsGenericParameters)
            {
                if (disableTypeAutoCreation)
                {
                    Debug.LogWarning($"Invalid [DisableAutoCreation] on {type.FullName} (only concrete types can be instantiated)");
                }

                return(false);
            }

            // only derivatives of ComponentSystemBase are systems
            if (!type.IsSubclassOf(typeof(ComponentSystemBase)))
            {
                throw new System.ArgumentException($"{type} must already be filtered by ComponentSystemBase");
            }

            if (requireExecuteAlways)
            {
                if (Attribute.IsDefined(type, typeof(ExecuteInEditMode)))
                {
                    Debug.LogError($"{type} is decorated with {typeof(ExecuteInEditMode)}. Support for this attribute will be deprecated. Please use {typeof(ExecuteAlways)} instead.");
                }
                if (!Attribute.IsDefined(type, typeof(ExecuteAlways)))
                {
                    return(false);
                }
            }

            // the auto-creation system instantiates using the default ctor, so if we can't find one, exclude from list
            if (type.GetConstructor(System.Type.EmptyTypes) == null)
            {
                // we want users to be explicit
                if (!disableTypeAutoCreation && !disableAllAutoCreation)
                {
                    Debug.LogWarning($"Missing default ctor on {type.FullName} (or if you don't want this to be auto-creatable, tag it with [DisableAutoCreation])");
                }

                return(false);
            }

            if (disableTypeAutoCreation || disableAllAutoCreation)
            {
                if (disableTypeAutoCreation && disableAllAutoCreation)
                {
                    Debug.LogWarning($"Redundant [DisableAutoCreation] on {type.FullName} (attribute is already present on assembly {type.Assembly.GetName().Name}");
                }

                return(false);
            }

            var systemFlags = WorldSystemFilterFlags.Default;

            if (Attribute.IsDefined(type, typeof(WorldSystemFilterAttribute), true))
            {
                systemFlags = type.GetCustomAttribute <WorldSystemFilterAttribute>(true).FilterFlags;
            }

            return((filterFlags & systemFlags) != 0);
        }
        public static List <Type> GetAllSystems(WorldSystemFilterFlags filterFlags)
        {
            IEnumerable <Type> allTypes;
            var systemTypes            = new List <Type>();
            ICustomBootstrap bootstrap = null;

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!TypeManager.IsAssemblyReferencingEntities(assembly))
                {
                    continue;
                }

                try
                {
                    allTypes = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException e)
                {
                    allTypes = e.Types.Where(t => t != null);
                    Debug.LogWarning(
                        $"DefaultWorldInitialization failed loading assembly: {(assembly.IsDynamic ? assembly.ToString() : assembly.Location)}");
                }

                var bootstrapTypes = allTypes.Where(t =>
                                                    typeof(ICustomBootstrap).IsAssignableFrom(t) &&
                                                    !t.IsAbstract &&
                                                    !t.ContainsGenericParameters);

                // TODO: should multiple bootstrap classes be allowed?
                foreach (var boot in bootstrapTypes)
                {
                    if (bootstrap == null)
                    {
                        bootstrap = Activator.CreateInstance(boot) as ICustomBootstrap;
                    }
                    else
                    {
                        Debug.LogError("Multiple custom bootstrappers specified, ignoring " + boot);
                    }
                }

                bool FilterSystemType(Type type)
                {
                    if (!type.IsSubclassOf(typeof(ComponentSystemBase)) || type.IsAbstract || type.ContainsGenericParameters)
                    {
                        return(false);
                    }

                    if (type.GetCustomAttribute <DisableAutoCreationAttribute>(true) != null)
                    {
                        return(false);
                    }

                    var systemFlags = WorldSystemFilterFlags.Default;
                    var attrib      = type.GetCustomAttribute <WorldSystemFilterAttribute>(true);

                    if (attrib != null)
                    {
                        systemFlags = attrib.FilterFlags;
                    }

                    return((filterFlags & systemFlags) != 0);
                }

                systemTypes.AddRange(allTypes.Where(FilterSystemType));
            }

            if (bootstrap != null)
            {
                systemTypes = bootstrap.Initialize(systemTypes);
            }

            return(systemTypes);
        }
Example #8
0
 /// <summary>For internal use only.</summary>
 /// <param name="flags">Defines where internal Unity systems should be created.</param>
 public WorldSystemFilterAttribute(WorldSystemFilterFlags flags)
 {
     FilterFlags = flags;
 }
        public static List <Type> GetAllSystems(WorldSystemFilterFlags filterFlags)
        {
            var systemTypes            = new List <Type>();
            ICustomBootstrap bootstrap = null;

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!TypeManager.IsAssemblyReferencingEntities(assembly))
                {
                    continue;
                }

                IReadOnlyList <Type> allTypes;
                try
                {
                    allTypes = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException e)
                {
                    allTypes = e.Types.Where(t => t != null).ToList();
                    Debug.LogWarning(
                        $"DefaultWorldInitialization failed loading assembly: {(assembly.IsDynamic ? assembly.ToString() : assembly.Location)}");
                }

                var bootstrapTypes = allTypes.Where(t =>
                                                    typeof(ICustomBootstrap).IsAssignableFrom(t) &&
                                                    !t.IsAbstract &&
                                                    !t.ContainsGenericParameters);

                // TODO: should multiple bootstrap classes be allowed?
                foreach (var boot in bootstrapTypes)
                {
                    if (bootstrap == null)
                    {
                        bootstrap = Activator.CreateInstance(boot) as ICustomBootstrap;
                    }
                    else
                    {
                        Debug.LogError("Multiple custom bootstrappers specified, ignoring " + boot);
                    }
                }

                // the entire assembly can be marked for no-auto-creation (test assemblies are good candidates for this)
                var disableAllAutoCreation = assembly.GetCustomAttribute <DisableAutoCreationAttribute>() != null;

                bool FilterSystemType(Type type)
                {
                    // IMPORTANT: keep this logic in sync with SystemTypeGen.cs for DOTS Runtime

                    var disableTypeAutoCreation = type.GetCustomAttribute <DisableAutoCreationAttribute>(false) != null;

                    // only derivatives of ComponentSystemBase are systems
                    if (!type.IsSubclassOf(typeof(ComponentSystemBase)))
                    {
                        if (disableTypeAutoCreation)
                        {
                            Debug.LogWarning($"Invalid [DisableAutoCreation] on {type.FullName} (only makes sense for {nameof(ComponentSystemBase)}-derived types)");
                        }

                        return(false);
                    }

                    // these types obviously cannot be instantiated
                    if (type.IsAbstract || type.ContainsGenericParameters)
                    {
                        if (disableTypeAutoCreation)
                        {
                            Debug.LogWarning($"Invalid [DisableAutoCreation] on {type.FullName} (only concrete types can be instantiated)");
                        }

                        return(false);
                    }

                    // the auto-creation system instantiates using the default ctor, so if we can't find one, exclude from list
                    if (type.GetConstructors().All(c => c.GetParameters().Length != 0))
                    {
                        // we want users to be explicit
                        if (!disableTypeAutoCreation && !disableAllAutoCreation)
                        {
                            Debug.LogWarning($"Missing default ctor on {type.FullName} (or if you don't want this to be auto-creatable, tag it with [DisableAutoCreation])");
                        }

                        return(false);
                    }

                    if (disableTypeAutoCreation || disableAllAutoCreation)
                    {
                        if (disableTypeAutoCreation && disableAllAutoCreation)
                        {
                            Debug.LogWarning($"Redundant [DisableAutoCreation] on {type.FullName} (attribute is already present on assembly {assembly.GetName().Name}");
                        }

                        return(false);
                    }

                    var systemFlags = WorldSystemFilterFlags.Default;
                    var attrib      = type.GetCustomAttribute <WorldSystemFilterAttribute>(true);

                    if (attrib != null)
                    {
                        systemFlags = attrib.FilterFlags;
                    }

                    return((filterFlags & systemFlags) != 0);
                }

                systemTypes.AddRange(allTypes.Where(FilterSystemType));
            }

            if (bootstrap != null)
            {
                systemTypes = bootstrap.Initialize(systemTypes);
            }

            return(systemTypes);
        }
        static bool FilterSystemType(Type type, LookupFlags lookupFlags)
        {
            // IMPORTANT: keep this logic in sync with SystemTypeGen.cs for DOTS Runtime
            WorldSystemFilterFlags systemFlags = WorldSystemFilterFlags.Default;

            // the entire assembly can be marked for no-auto-creation (test assemblies are good candidates for this)
            var disableAllAutoCreation  = Attribute.IsDefined(type.Assembly, typeof(DisableAutoCreationAttribute));
            var disableTypeAutoCreation = Attribute.IsDefined(type, typeof(DisableAutoCreationAttribute), false);

            // these types obviously cannot be instantiated
            if (type.IsAbstract || type.ContainsGenericParameters)
            {
                if (disableTypeAutoCreation)
                {
                    Debug.LogWarning($"Invalid [DisableAutoCreation] on {type.FullName} (only concrete types can be instantiated)");
                }

                return(false);
            }

            // only derivatives of ComponentSystemBase and structs implementing ISystemBase are systems
            if (!type.IsSubclassOf(typeof(ComponentSystemBase)) && !typeof(ISystemBase).IsAssignableFrom(type))
            {
                throw new System.ArgumentException($"{type} must already be filtered by ComponentSystemBase");
            }

            // the auto-creation system instantiates using the default ctor, so if we can't find one, exclude from list
            if (type.IsClass && type.GetConstructor(Type.EmptyTypes) == null)
            {
                // we want users to be explicit
                if (!disableTypeAutoCreation && !disableAllAutoCreation)
                {
                    Debug.LogWarning($"Missing default ctor on {type.FullName} (or if you don't want this to be auto-creatable, tag it with [DisableAutoCreation])");
                }

                return(false);
            }

            if (lookupFlags.OptionalFlags == WorldSystemFilterFlags.All)
            {
                return(true);
            }

            if (disableTypeAutoCreation || disableAllAutoCreation)
            {
                if (disableTypeAutoCreation && disableAllAutoCreation)
                {
                    Debug.LogWarning($"Redundant [DisableAutoCreation] on {type.FullName} (attribute is already present on assembly {type.Assembly.GetName().Name}");
                }

                return(false);
            }

            if (Attribute.IsDefined(type, typeof(WorldSystemFilterAttribute), true))
            {
                systemFlags = type.GetCustomAttribute <WorldSystemFilterAttribute>(true).FilterFlags;
            }

            if ((lookupFlags.RequiredFlags & WorldSystemFilterFlags.Editor) != 0)
            {
                lookupFlags.OptionalFlags |= WorldSystemFilterFlags.Editor;

#if !UNITY_DOTSRUNTIME
                if (Attribute.IsDefined(type, typeof(ExecuteInEditMode)))
                {
                    Debug.LogError($"{type} is decorated with {typeof(ExecuteInEditMode)}. Support for this attribute will be deprecated. Please use [WorldSystemFilter(WorldSystemFilterFlags.EditTime)] instead.");
                }
#endif
                if (Attribute.IsDefined(type, typeof(ExecuteAlways)))
                {
                    // Until we formally deprecate ExecuteAlways, add in the Editor flag as this has the same meaning
                    // When we deprecate uncomment the log error below
                    //Debug.LogError($"{type} is decorated with {typeof(ExecuteAlways)}. Support for this attribute will be deprecated. Please use [WorldSystemFilter(WorldSystemFilterFlags.EditTime)] instead.");

                    systemFlags |= WorldSystemFilterFlags.Editor;
                }
            }

            return((lookupFlags.OptionalFlags & systemFlags) >= lookupFlags.RequiredFlags);
        }
Example #11
0
 public static IEnumerable <Type> GetDefaultInitSystemsFromEntitiesPackage(WorldSystemFilterFlags flags) => FilterSystemsToPackages(
     DefaultWorldInitialization.GetAllSystems(flags), EntitiesPackage
     );
 /// <summary>
 /// Calculates a list of all systems filtered with WorldSystemFilterFlags, [DisableAutoCreation] etc.
 /// </summary>
 /// <param name="filterFlags"></param>
 /// <param name="requireExecuteAlways">Optionally require that [ExecuteAlways] is present on the system. This is used when creating edit mode worlds.</param>
 /// <returns>The list of filtered systems</returns>
 public static IReadOnlyList <Type> GetAllSystems(WorldSystemFilterFlags filterFlags, bool requireExecuteAlways = false)
 {
     return(TypeManager.GetSystems(filterFlags, requireExecuteAlways ? WorldSystemFilterFlags.Editor : WorldSystemFilterFlags.Default));
 }