/// <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 }
/// <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); }
/// <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); }
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); }
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); }
/// <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); }
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)); }