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