예제 #1
0
        /// <summary>
        /// Injects custom data to fields of ISystem instance.
        /// </summary>
        /// <param name="system">ISystem instance.</param>
        /// <param name="world">EcsWorld instance.</param>
        /// <param name="injections">Additional instances for injection.</param>
        public static void InjectDataToSystem(IEcsSystem system, EcsWorld world, Dictionary <Type, object> injections)
        {
            var systemType = system.GetType();
            var worldType  = world.GetType();
            var filterType = typeof(EcsFilter);
            var ignoreType = typeof(EcsIgnoreInjectAttribute);

            foreach (var f in systemType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                // skip statics or fields with [EcsIgnoreInject] attribute.
                if (f.IsStatic || Attribute.IsDefined(f, ignoreType))
                {
                    continue;
                }
                // EcsWorld
                if (f.FieldType.IsAssignableFrom(worldType))
                {
                    f.SetValue(system, world);
                    continue;
                }
                // EcsFilter
#if DEBUG
                if (f.FieldType == filterType)
                {
                    throw new Exception(string.Format("Cant use EcsFilter type at \"{0}\" system for dependency injection, use generic version instead", system));
                }
#endif
                if (f.FieldType.IsSubclassOf(filterType))
                {
                    f.SetValue(system, world.GetFilter(f.FieldType));
                    continue;
                }
                // Other injections.
                foreach (var pair in injections)
                {
                    if (f.FieldType.IsAssignableFrom(pair.Key))
                    {
                        f.SetValue(system, pair.Value);
                        break;
                    }
                }
            }
        }
예제 #2
0
파일: EcsSystem.cs 프로젝트: alanyuen/ecs
        /// <summary>
        /// Adds new system to processing.
        /// </summary>
        /// <param name="system">System instance.</param>
        /// <param name="namedRunSystem">Optional name of system.</param>
        public EcsSystems Add(IEcsSystem system, string namedRunSystem = null)
        {
#if DEBUG
            if (system == null)
            {
                throw new Exception("System is null.");
            }
            if (_inited)
            {
                throw new Exception("Cant add system after initialization.");
            }
            if (_destroyed)
            {
                throw new Exception("Cant touch after destroy.");
            }
            if (!string.IsNullOrEmpty(namedRunSystem) && !(system is IEcsRunSystem))
            {
                throw new Exception("Cant name non-IEcsRunSystem.");
            }
#endif
            _allSystems.Add(system);
            if (system is IEcsRunSystem)
            {
                if (namedRunSystem != null)
                {
                    _namedRunSystems[namedRunSystem.GetHashCode()] = _runSystems.Count;
                }
                else
                {
                    _namedRunSystems[system.GetType().Name.GetHashCode()] = _runSystems.Count;
                }
                _runSystems.Add(new EcsSystemsRunItem()
                {
                    Active = true, System = (IEcsRunSystem)system
                });
            }
            return(this);
        }
예제 #3
0
 public void AddSystem(IEcsSystem system)
 {
     AddSystem(GetSystemGroupHierarchy(system.GetType()), system);
 }
예제 #4
0
        public void ActivateSystem(IEcsSystem system, LeoSystemData systemData)
        {
            var systemType = system.GetType();

            ActivateSystem(systemType, systemData, system);
        }
예제 #5
0
        public void ActivateSystem(IEcsSystem system)
        {
            var systemType = system.GetType();

            ActivateSystem(systemType, CreateSystemInfo(systemType), system);
        }
예제 #6
0
        public static void Inject(EcsWorld world, IEcsSystem system)
        {
            var worldType            = world.GetType();
            var systemType           = system.GetType();
            var ecsFilter            = typeof(EcsFilter);
            var ecsIndex             = typeof(int);
            var attrEcsWorld         = typeof(EcsWorldAttribute);
            var attrEcsFilterInclude = typeof(EcsFilterIncludeAttribute);
            var attrEcsFilterExclude = typeof(EcsFilterExcludeAttribute);
            var attrEcsIndex         = typeof(EcsIndexAttribute);

            foreach (var f in systemType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                // [EcsWorld]
                if (f.FieldType.IsAssignableFrom(worldType) && !f.IsStatic && Attribute.IsDefined(f, attrEcsWorld))
                {
                    f.SetValue(system, world);
                }

                // [EcsFilterInclude]
                if (f.FieldType == ecsFilter && !f.IsStatic)
                {
                    EcsComponentMask includeMask = null;
                    var standardFilterIncDefined = Attribute.IsDefined(f, attrEcsFilterInclude);
                    if (standardFilterIncDefined)
                    {
                        includeMask = new EcsComponentMask();
                        var components = ((EcsFilterIncludeAttribute)Attribute.GetCustomAttribute(f, attrEcsFilterInclude)).Components;
                        for (var i = 0; i < components.Length; i++)
                        {
                            includeMask.SetBit(world.GetComponentIndex(components[i]), true);
                        }
                    }
                    EcsComponentMask excludeMask = null;
                    var standardFilterExcDefined = Attribute.IsDefined(f, attrEcsFilterExclude);
                    if (standardFilterExcDefined)
                    {
                        excludeMask = new EcsComponentMask();
                        var components = ((EcsFilterExcludeAttribute)Attribute.GetCustomAttribute(f, attrEcsFilterExclude)).Components;
                        for (var i = 0; i < components.Length; i++)
                        {
                            excludeMask.SetBit(world.GetComponentIndex(components[i]), true);
                        }
                    }
#if DEBUG && !ECS_PERF_TEST
                    if (standardFilterIncDefined && includeMask.IsEmpty())
                    {
                        throw new Exception("Include filter cant be empty at system: " + systemType.Name);
                    }
                    if (standardFilterExcDefined && excludeMask.IsEmpty())
                    {
                        throw new Exception("Exclude filter cant be empty at system: " + systemType.Name);
                    }
                    if (!standardFilterIncDefined && standardFilterExcDefined)
                    {
                        throw new Exception("EcsFilterExclude can be applied only as pair to EcsFilterInclude at system: " + systemType.Name);
                    }
                    if (includeMask != null && excludeMask != null && includeMask.IsIntersects(excludeMask))
                    {
                        throw new Exception("Exclude and include filters are intersected at system: " + systemType.Name);
                    }
#endif
                    if (standardFilterIncDefined)
                    {
                        f.SetValue(system, world.GetFilter(includeMask, excludeMask ?? new EcsComponentMask()));
                    }
                }

                // [EcsIndex]
                if (f.FieldType == ecsIndex && !f.IsStatic && Attribute.IsDefined(f, attrEcsIndex))
                {
                    var component = ((EcsIndexAttribute)Attribute.GetCustomAttribute(f, attrEcsIndex)).Component;
                    f.SetValue(system, world.GetComponentIndex(component));
                }
            }
        }