Esempio n. 1
0
        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());
        }
Esempio n. 3
0
        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);
        }
Esempio n. 11
0
 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";