private void RemoveSystemInternal(ComponentSystemBase system) { if (!m_Systems.Remove(system)) { throw new ArgumentException($"System does not exist in the world"); } ++Version; #if !UNITY_DOTSPLAYER var type = system.GetType(); while (type != typeof(ComponentSystemBase)) { if (m_SystemLookup[type] == system) { m_SystemLookup.Remove(type); foreach (var otherSystem in m_Systems) { if (otherSystem.GetType().IsSubclassOf(type)) { AddTypeLookup(otherSystem.GetType(), otherSystem); } } } type = type.BaseType; } #endif }
private static void InjectFields(ComponentSystemBase componentSystem, World world, EntityManager entityManager, out InjectComponentGroupData[] outInjectGroups, out InjectFromEntityData outInjectFromEntityData) { List <InjectComponentGroupData> list = new List <InjectComponentGroupData>(); List <InjectionData> componentDataFromEntity = new List <InjectionData>(); List <InjectionData> bufferFromEntity = new List <InjectionData>(); foreach (FieldInfo info in componentSystem.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { object[] customAttributes = info.GetCustomAttributes(typeof(InjectAttribute), true); if (customAttributes.Length != 0) { if (info.FieldType.IsClass) { InjectConstructorDependencies(componentSystem, world, info); } else if (InjectFromEntityData.SupportsInjections(info)) { InjectFromEntityData.CreateInjection(info, entityManager, componentDataFromEntity, bufferFromEntity); } else { list.Add(InjectComponentGroupData.CreateInjection(info.FieldType, info, componentSystem)); } } } outInjectGroups = list.ToArray(); outInjectFromEntityData = new InjectFromEntityData(componentDataFromEntity.ToArray(), bufferFromEntity.ToArray()); }
public void AddSystemToUpdateList(ComponentSystemBase sys) { if (sys != null) { if (this == sys) { #if !NET_DOTS throw new ArgumentException($"Can't add {GetType()} to its own update list"); #else throw new ArgumentException($"Can't add a ComponentSystemGroup to its own update list"); #endif } if (sys.World != World) { Debug.LogWarning($"'{sys.GetType()}' can't be added to '{GetType()}' because they are in different worlds. ('{sys.World.Name}' vs '{World.Name}')"); } // Check for duplicate Systems. Also see issue #1792 if (m_systemsToUpdate.IndexOf(sys) >= 0) { return; } m_systemsToUpdate.Add(sys); m_systemSortDirty = true; } }
static bool AppendSystemToPlayerLoopListImpl(ComponentSystemBase system, ref PlayerLoopSystem playerLoop, Type playerLoopSystemType) { if (playerLoop.type == playerLoopSystemType) { var del = new DummyDelegateWrapper(system); int oldListLength = (playerLoop.subSystemList != null) ? playerLoop.subSystemList.Length : 0; var newSubsystemList = new PlayerLoopSystem[oldListLength + 1]; for (var i = 0; i < oldListLength; ++i) { newSubsystemList[i] = playerLoop.subSystemList[i]; } newSubsystemList[oldListLength].type = system.GetType(); newSubsystemList[oldListLength].updateDelegate = del.TriggerUpdate; playerLoop.subSystemList = newSubsystemList; return(true); } if (playerLoop.subSystemList != null) { for (int i = 0; i < playerLoop.subSystemList.Length; ++i) { if (AppendSystemToPlayerLoopListImpl(system, ref playerLoop.subSystemList[i], playerLoopSystemType)) { return(true); } } } return(false); }
public static void Inject(ComponentSystemBase componentSystem, World world, EntityManager entityManager, out InjectComponentGroupData[] outInjectGroups, out InjectFromEntityData outInjectFromEntityData) { var componentSystemType = componentSystem.GetType(); ValidateNoStaticInjectDependencies(componentSystemType); InjectFields(componentSystem, world, entityManager, out outInjectGroups, out outInjectFromEntityData); }
/// <summary> /// Call this to add a System that was manually constructed; normally these /// Systems are marked with [DisableAutoCreation]. /// </summary> public static void AddSystem(World world, ComponentSystemBase system) { if (world.GetExistingSystem(system.GetType()) != null) { throw new ArgumentException("AddSystem: Error to add a duplicate system."); } world.AddSystem(system); AddSystemToGroup(world, system); }
public static void Inject(ComponentSystemBase componentSystem, World world, EntityManager entityManager, out InjectComponentGroupData[] outInjectGroups, out InjectFromEntityData outInjectFromEntityData) { var componentSystemType = componentSystem.GetType(); ValidateNoStaticInjectDependencies(componentSystemType); var fields = componentSystemType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var injectGroups = new List <InjectComponentGroupData>(); var injectFromEntity = new List <InjectionData>(); var injectFromFixedArray = new List <InjectionData>(); foreach (var field in fields) { var attr = field.GetCustomAttributes(typeof(InjectAttribute), true); if (attr.Length == 0) { continue; } if (field.FieldType.IsClass) { InjectConstructorDependencies(componentSystem, world, field); } else { if (InjectFromEntityData.SupportsInjections(field)) { InjectFromEntityData.CreateInjection(field, entityManager, injectFromEntity, injectFromFixedArray); } else { injectGroups.Add( InjectComponentGroupData.CreateInjection(field.FieldType, field, componentSystem)); } } } outInjectGroups = injectGroups.ToArray(); outInjectFromEntityData = new InjectFromEntityData(injectFromEntity.ToArray(), injectFromFixedArray.ToArray()); }
private static void AddSystemToGroup(World world, ComponentSystemBase system) { var groups = TypeManager.GetSystemAttributes(system.GetType(), typeof(UpdateInGroupAttribute)); if (groups.Length == 0) { var simulationSystemGroup = world.GetExistingSystem <SimulationSystemGroup>(); simulationSystemGroup.AddSystemToUpdateList(system); } for (int g = 0; g < groups.Length; ++g) { var groupType = groups[g] as UpdateInGroupAttribute; var groupSystem = world.GetExistingSystem(groupType.GroupType) as ComponentSystemGroup; if (groupSystem == null) { throw new Exception("AddSystem failed to find existing SystemGroup."); } groupSystem.AddSystemToUpdateList(system); } }
private void FlushBuffers(bool playBack) { this.m_ProducerHandle.Complete(); this.m_ProducerHandle = new JobHandle(); int count = this.m_PendingBuffers.Count; Exception exception = null; int num2 = 0; while (true) { if (num2 >= count) { this.m_PendingBuffers.Clear(); if (exception != null) { throw exception; } return; } EntityCommandBuffer buffer = this.m_PendingBuffers[num2]; if (playBack) { try { buffer.Playback(base.EntityManager); } catch (Exception exception2) { ComponentSystemBase systemFromSystemID = base.GetSystemFromSystemID(base.World, buffer.SystemID); string str = (systemFromSystemID != null) ? systemFromSystemID.GetType().ToString() : "Unknown"; exception = new ArgumentException($"{exception2.Message} EntityCommandBuffer was recorded in {str} and played back in {base.GetType()}. " + exception2.StackTrace); } } buffer.Dispose(); num2++; } }
private static string CollectInjectedGroup(ComponentSystemBase system, FieldInfo groupField, Type injectedGroupType, out FieldInfo entityArrayField, out FieldInfo indexFromEntityField, InjectionContext injectionContext, out FieldInfo lengthField, out FieldInfo componentGroupIndexField, ISet <ComponentType> componentRequirements, ICollection <InjectionData> componentDataInjections, ICollection <InjectionData> bufferDataInjections, ICollection <InjectionData> sharedComponentInjections) { //@TODO: Improve error messages... var fields = injectedGroupType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); entityArrayField = null; indexFromEntityField = null; lengthField = null; componentGroupIndexField = null; foreach (var field in fields) { var isReadOnly = field.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0; //@TODO: Prevent using GameObjectEntity, it will never show up. Point to GameObjectArray instead... if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(ComponentDataArray <>)) { var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); componentDataInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>)) { componentRequirements.Add(ComponentType.Subtractive(field.FieldType.GetGenericArguments()[0])); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(BufferArray <>)) { var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); bufferDataInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(SharedComponentDataArray <>)) { if (!isReadOnly) { return ($"{system.GetType().Name}:{groupField.Name} SharedComponentDataArray<> must always be injected as [ReadOnly]"); } var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], true); sharedComponentInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType == typeof(EntityArray)) { // Error on multiple EntityArray if (entityArrayField != null) { return ($"{system.GetType().Name}:{groupField.Name} An [Inject] struct, may only contain a single EntityArray"); } entityArrayField = field; } else if (field.FieldType == typeof(int)) { if (field.Name != "Length" && field.Name != "GroupIndex") { return ($"{system.GetType().Name}:{groupField.Name} Int in an [Inject] struct should be named \"Length\" (group length) or \"GroupIndex\" (index in ComponentGroup[])"); } if (!field.IsInitOnly) { return ($"{system.GetType().Name}:{groupField.Name} {field.Name} must use the \"readonly\" keyword"); } if (field.Name == "Length") { lengthField = field; } if (field.Name == "GroupIndex") { componentGroupIndexField = field; } } else { var hook = InjectionHookSupport.HookFor(field); if (hook == null) { return ($"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", InjectionHookSupport.Hooks.Select(h => h.FieldTypeOfInterest.Name))} and int Length."); } var error = hook.ValidateField(field, isReadOnly, injectionContext); if (error != null) { return(error); } injectionContext.AddEntry(hook.CreateInjectionInfoFor(field, isReadOnly)); } } if (injectionContext.HasComponentRequirements) { foreach (var requirement in injectionContext.ComponentRequirements) { componentRequirements.Add(requirement); } } return(null); }
void AddSystem_Add_Internal(ComponentSystemBase system) { m_Systems.Add(system); AddTypeLookupInternal(system.GetType(), system); }
private static string CollectInjectedGroup(ComponentSystemBase system, FieldInfo groupField, Type injectedGroupType, out FieldInfo entityArrayField, out FieldInfo indexFromEntityField, InjectionContext injectionContext, out FieldInfo lengthField, out FieldInfo componentGroupIndexField, ISet <ComponentType> componentRequirements, ICollection <InjectionData> componentDataInjections, ICollection <InjectionData> bufferDataInjections, ICollection <InjectionData> sharedComponentInjections) { string str; FieldInfo[] fields = injectedGroupType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); entityArrayField = null; indexFromEntityField = null; lengthField = null; componentGroupIndexField = null; FieldInfo[] infoArray2 = fields; int index = 0; while (true) { if (index >= infoArray2.Length) { if (injectionContext.HasComponentRequirements) { foreach (ComponentType type in injectionContext.ComponentRequirements) { componentRequirements.Add(type); } } str = null; break; } FieldInfo field = infoArray2[index]; bool isReadOnly = field.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0; if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(ComponentDataArray <>))) { InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); componentDataInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>))) { componentRequirements.Add(ComponentType.Subtractive(field.FieldType.GetGenericArguments()[0])); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(BufferArray <>))) { InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); bufferDataInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(SharedComponentDataArray <>))) { if (!isReadOnly) { str = $"{system.GetType().Name}:{groupField.Name} SharedComponentDataArray<> must always be injected as [ReadOnly]"; break; } InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], true); sharedComponentInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType == typeof(EntityArray)) { if (entityArrayField != null) { str = $"{system.GetType().Name}:{groupField.Name} An [Inject] struct, may only contain a single EntityArray"; break; } entityArrayField = field; } else if (!(field.FieldType == typeof(int))) { InjectionHook hook = InjectionHookSupport.HookFor(field); if (hook == null) { str = $"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", (IEnumerable<string>) (from h in InjectionHookSupport.Hooks select h.FieldTypeOfInterest.Name))} and int Length."; break; } string str2 = hook.ValidateField(field, isReadOnly, injectionContext); if (str2 != null) { str = str2; break; } injectionContext.AddEntry(hook.CreateInjectionInfoFor(field, isReadOnly)); } else { if ((field.Name != "Length") && (field.Name != "GroupIndex")) { str = $"{system.GetType().Name}:{groupField.Name} Int in an [Inject] struct should be named " Length " (group length) or " GroupIndex " (index in ComponentGroup[])"; break; } if (!field.IsInitOnly) { str = $"{system.GetType().Name}:{groupField.Name} {field.Name} must use the " readonly " keyword";