public void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, EGID?toEntityID,
                                                       ITypeSafeDictionary toGroup,
                                                       Dictionary <Type, FasterList <IEngine> > engines,
                                                       ref PlatformProfiler profiler)
        {
            var valueIndex = GetValueIndex(fromEntityGid.entityID);

            if (toGroup != null)
            {
                RemoveEntityViewFromEngines(engines, ref _values[valueIndex], fromEntityGid.groupID, ref profiler);

                var     toGroupCasted = toGroup as TypeSafeDictionary <TValue>;
                ref var entity        = ref _values[valueIndex];
                var     previousGroup = fromEntityGid.groupID;

                ///
                /// NOTE I WOULD EVENTUALLY NEED TO REUSE THE REAL ID OF THE REMOVING ELEMENT
                /// SO THAT I CAN DECREASE THE GLOBAL GROUP COUNT
                ///

                //      entity.ID = EGID.UPDATE_REAL_ID_AND_GROUP(entity.ID, toEntityID.groupID, entityCount);
                if (HasEgid)
                {
                    var needEgid = (INeedEGID)entity;
                    needEgid.ID = toEntityID.Value;
                    entity      = (TValue)needEgid;
                }

                var index = toGroupCasted.Add(fromEntityGid.entityID, ref entity);

                AddEntityViewToEngines(engines, ref toGroupCasted._values[index], previousGroup,
                                       ref profiler);
            }
예제 #2
0
        public void BuildEntityViewAndAddToList(ref ITypeSafeDictionary dictionary, EGID entityID, object[] implementors)
        {
            if (dictionary == null)
            {
                dictionary = new TypeSafeDictionary <T>();
            }

            var castedDic = dictionary as TypeSafeDictionary <T>;

            if (needsReflection == true)
            {
                DBC.ECS.Check.Require(implementors != null, "Implementors not found while building an EntityView");

                T lentityView;
                EntityView <T> .BuildEntityView(entityID, out lentityView);

                this.FillEntityView(ref lentityView
                                    , entityViewBlazingFastReflection
                                    , implementors
                                    , DESCRIPTOR_NAME);

                castedDic.Add(entityID.entityID, ref lentityView);
            }
            else
            {
                _initializer.ID = entityID;

                castedDic.Add(entityID.entityID, _initializer);
            }
        }
        /// <summary>
        /// Add entities from external typeSafeDictionary
        /// </summary>
        /// <param name="entitiesToSubmit"></param>
        /// <param name="groupId"></param>
        /// <exception cref="TypeSafeDictionaryException"></exception>
        public void AddEntitiesFromDictionary(ITypeSafeDictionary entitiesToSubmit, uint groupId)
        {
            var typeSafeDictionary = entitiesToSubmit as FastTypeSafeDictionary <TValue>;

            foreach (var tuple in typeSafeDictionary)
            {
                try
                {
                    if (_hasEgid)
                    {
                        SetEGIDWithoutBoxing <TValue> .SetIDWithoutBoxing(ref typeSafeDictionary.unsafeValues[tuple.Key],
                                                                          new EGID(tuple.Key, groupId));
                    }

                    _implementation.Add(tuple.Value);
                }
                catch (Exception e)
                {
                    throw new
                          TypeSafeDictionaryException("trying to add an EntityComponent with the same ID more than once Entity: ".
                                                      FastConcat(typeof(TValue).ToString()).FastConcat(", group ").
                                                      FastConcat(groupId).FastConcat(", id ").FastConcat(tuple.Key), e);
                }
            }
        }
예제 #4
0
        internal static EGIDMapper <T> ToEGIDMapper <T>(this ITypeSafeDictionary <T> dic,
                                                        ExclusiveGroupStruct groupStructId) where T : struct, IBaseEntityComponent
        {
            var mapper = new EGIDMapper <T>(groupStructId, dic);

            return(mapper);
        }
예제 #5
0
        void MoveEntity(EGID fromEntityGID, int toGroupID, Dictionary <Type, ITypeSafeDictionary> toGroup, Type entityType)
        {
            var fromGroup = _groupEntityDB[fromEntityGID.groupID];

            var fromTypeSafeDictionary         = fromGroup[entityType];
            ITypeSafeDictionary safeDictionary = null;

            if (toGroup != null)
            {
                if (toGroup.TryGetValue(entityType, out safeDictionary) == false)
                {
                    safeDictionary = fromTypeSafeDictionary.Create();
                    toGroup.Add(entityType, safeDictionary);
                    _groupedGroups[entityType] = new FasterDictionary <int, ITypeSafeDictionary>();
                }

                _groupedGroups[entityType][toGroupID] = safeDictionary;
            }

            fromTypeSafeDictionary.MoveEntityFromDictionaryAndEngines(fromEntityGID, toGroupID, safeDictionary, _entityEngines);

            if (fromTypeSafeDictionary.Count == 0) //clean up
            {
                _groupedGroups[entityType].Remove(fromEntityGID.groupID);

                //it's probably better to not remove this, but the dictionary should be trimmed?
                //fromGroup.Remove(entityType);
                fromTypeSafeDictionary.Trim();
            }

            //it doesn't eliminate the fromGroup itself on purpose
        }
예제 #6
0
        public void BuildEntityAndAddToList(ref ITypeSafeDictionary dictionary, EGID entityID, object[] implementors)
        {
            if (dictionary == null)
            {
                dictionary = new TypeSafeDictionary <T>();
            }

            var castedDic = dictionary as TypeSafeDictionary <T>;

            if (NEEDS_REFLECTION == true)
            {
                DBC.ECS.Check.Require(implementors != null, "Implementors not found while building an EntityView");
                DBC.ECS.Check.Require(castedDic.ContainsKey(entityID.entityID) == false,
                                      "building an entity with already used entity id! id".FastConcat(entityID).FastConcat(" ", ENTITY_VIEW_NAME));

                T entityView;
                EntityView <T> .BuildEntityView(entityID, out entityView);

                this.FillEntityView(ref entityView
                                    , entityViewBlazingFastReflection
                                    , implementors);

                castedDic.Add(entityID.entityID, ref entityView);
            }
            else
            {
                _initializer.ID = entityID;

                castedDic.Add(entityID.entityID, _initializer);
            }
        }
        public void AddEntitiesFromDictionary(ITypeSafeDictionary entitiesToSubmit, uint groupId)
        {
            var typeSafeDictionary = entitiesToSubmit as TypeSafeDictionary <TValue>;

            foreach (var tuple in typeSafeDictionary)
            {
                try
                {
                    if (HasEgid)
                    {
                        var needEgid = (INeedEGID)tuple.Value;
                        needEgid.ID = new EGID(tuple.Key, groupId);
                        Add(tuple.Key, (TValue)needEgid);
                    }
                    else
                    {
                        Add(tuple.Key, ref tuple.Value);
                    }
                }
                catch (Exception e)
                {
                    throw new TypeSafeDictionaryException(
                              "trying to add an EntityView with the same ID more than once Entity: "
                              .FastConcat(typeof(TValue).ToString()).FastConcat("id ").FastConcat(tuple.Key), e);
                }
            }
        }
예제 #8
0
            public bool MoveNext()
            {
                //attention, the while is necessary to skip empty groups
                while (_db.MoveNext() == true)
                {
                    var group = _db.Current;
                    if (group.key.IsEnabled() == false)
                    {
                        continue;
                    }

                    ITypeSafeDictionary <T1> typeSafeDictionary = @group.value as ITypeSafeDictionary <T1>;

                    if (typeSafeDictionary.count == 0)
                    {
                        continue;
                    }
                    _array.collection = new EntityCollection <T1>(typeSafeDictionary.GetValues(out var count),
                                                                  typeSafeDictionary.entityIDs, count);
                    _array.@group = group.key;
                    return(true);
                }

                return(false);
            }
예제 #9
0
        public static void MoveEntityView(EGID entityID, int toGroupID, ITypeSafeDictionary fromSafeDic, ITypeSafeDictionary toSafeDic)
        {
            var fromCastedDic = fromSafeDic as TypeSafeDictionary <T>;
            var toCastedDic   = toSafeDic as TypeSafeDictionary <T>;

            var entity = fromCastedDic[entityID.entityID];

            fromCastedDic.Remove(entityID.entityID);
            entity.ID = new EGID(entityID.entityID, toGroupID);
            toCastedDic.Add(entityID.entityID, entity);
        }
        public void AddEntitiesToEngines(
            Dictionary <Type, FasterList <IEngine> > entityViewEnginesDB,
            ITypeSafeDictionary realDic, ref PlatformProfiler profiler)
        {
            foreach (var value in this)
            {
                var typeSafeDictionary = realDic as TypeSafeDictionary <TValue>;

                AddEntityViewToEngines(entityViewEnginesDB, ref typeSafeDictionary.GetDirectValue(value.Key), null,
                                       ref profiler);
            }
        }
예제 #11
0
        static void BuildEntity
            (EGID entityID, FasterDictionary <RefWrapperType, ITypeSafeDictionary> group
            , IComponentBuilder componentBuilder, IEnumerable <object> implementors)
        {
            var entityComponentType            = componentBuilder.GetEntityComponentType();
            ITypeSafeDictionary safeDictionary = group.GetOrAdd(new RefWrapperType(entityComponentType)
                                                                , (ref IComponentBuilder cb) => cb.CreateDictionary(1)
                                                                , ref componentBuilder);

            //   if the safeDictionary hasn't been created yet, it will be created inside this method.
            componentBuilder.BuildEntityAndAddToList(safeDictionary, entityID, implementors);
        }
        public void Serialize(uint entityID, ITypeSafeDictionary dictionary, ISerializationData serializationData
                              , int serializationType)
        {
            IComponentSerializer <T> componentSerializer = _serializers[serializationType];

            var safeDictionary = (ITypeSafeDictionary <T>)dictionary;

            if (safeDictionary.TryFindIndex(entityID, out uint index) == false)
            {
                throw new ECSException("Entity Serialization failed");
            }

            ref T val = ref safeDictionary.GetDirectValueByRef(index);
예제 #13
0
        public static ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary dictionary, int size)
        {
            if (dictionary == null)
            {
                dictionary = new TypeSafeDictionary <T>(size);
            }
            else
            {
                dictionary.AddCapacity(size);
            }

            return(dictionary);
        }
예제 #14
0
        void MoveEntityView(EGID entityGID, EGID?toEntityGID, Dictionary <Type, ITypeSafeDictionary> toGroup,
                            ref Dictionary <Type, ITypeSafeDictionary> fromGroup, Type entityViewType, PlatformProfiler profiler)
        {
            if (fromGroup.TryGetValue(entityViewType, out var fromTypeSafeDictionary) == false)
            {
                throw new ECSException("no entities in from group eid: ".FastConcat(entityGID.entityID)
                                       .FastConcat(" group: ").FastConcat(entityGID.groupID));
            }

            ITypeSafeDictionary toEntitiesDictionary = null;

            //in case we want to move to a new group, otherwise is just a remove
            if (toEntityGID != null)
            {
                if (toGroup.TryGetValue(entityViewType, out toEntitiesDictionary) == false)
                {
                    toEntitiesDictionary = fromTypeSafeDictionary.Create();
                    toGroup.Add(entityViewType, toEntitiesDictionary);
                }

                if (_groupsPerEntity.TryGetValue(entityViewType, out var groupedGroup) == false)
                {
                    groupedGroup = _groupsPerEntity[entityViewType] = new FasterDictionary <uint, ITypeSafeDictionary>();
                }

                groupedGroup[toEntityGID.Value.groupID] = toEntitiesDictionary;
            }

            if (fromTypeSafeDictionary.Has(entityGID.entityID) == false)
            {
                throw new EntityNotFoundException(entityGID, entityViewType);
            }

            fromTypeSafeDictionary.MoveEntityFromDictionaryAndEngines(entityGID, toEntityGID,
                                                                      toEntitiesDictionary,
                                                                      toEntityGID == null ? _reactiveEnginesAddRemove :
                                                                      _reactiveEnginesSwap,
                                                                      ref profiler);

            if (fromTypeSafeDictionary.Count == 0) //clean up
            {
                _groupsPerEntity[entityViewType].Remove(entityGID.groupID);

                //I don't remove the group if empty on purpose, in case it needs to be reused however I trim it to save
                //memory
                fromTypeSafeDictionary.Trim();
            }
        }
        public void AddEntityToDictionary(EGID fromEntityGid, EGID toEntityID, ITypeSafeDictionary toGroup)
        {
            var valueIndex = _implementation.GetIndex(fromEntityGid.entityID);

            if (toGroup != null)
            {
                var     toGroupCasted = toGroup as ITypeSafeDictionary <TValue>;
                ref var entity        = ref _implementation.unsafeValues[(int)valueIndex];

                if (_hasEgid)
                {
                    SetEGIDWithoutBoxing <TValue> .SetIDWithoutBoxing(ref entity, toEntityID);
                }

                toGroupCasted.Add(fromEntityGid.entityID, entity);
            }
예제 #16
0
        public void FillWithIndexedEntities(ITypeSafeDictionary entities)
        {
            int count;
            var buffer = (entities as TypeSafeDictionary <TValue>).GetValuesArray(out count);

            try
            {
                for (var i = 0; i < count; i++)
                {
                    Add(buffer[i].ID.entityID, ref buffer[i]);
                }
            }
            catch (Exception e)
            {
                throw new TypeSafeDictionaryException(e);
            }
        }
예제 #17
0
        void MoveEntityView(EGID entityGID, int toGroupID, Dictionary <Type, ITypeSafeDictionary> toGroup,
                            Dictionary <Type, ITypeSafeDictionary> fromGroup, Type entityType)
        {
            ITypeSafeDictionary fromTypeSafeDictionary;

            if (fromGroup.TryGetValue(entityType, out fromTypeSafeDictionary) == false)
            {
                throw new ECSException("no entities in from group eid: ".FastConcat(entityGID.entityID).FastConcat(" group: ").FastConcat(entityGID.groupID));
            }

            ITypeSafeDictionary dictionaryOfEntities         = null;

            //in case we want to move to a new group, otherwise is just a remove
            if (toGroup != null)
            {
                if (toGroup.TryGetValue(entityType, out dictionaryOfEntities) == false)
                {
                    dictionaryOfEntities = fromTypeSafeDictionary.Create();
                    toGroup.Add(entityType, dictionaryOfEntities);
                }

                FasterDictionary <int, ITypeSafeDictionary> groupedGroup;
                if (_groupedGroups.TryGetValue(entityType, out groupedGroup) == false)
                {
                    groupedGroup = _groupedGroups[entityType] = new FasterDictionary <int, ITypeSafeDictionary>();
                }

                groupedGroup[toGroupID] = dictionaryOfEntities;
            }

            if (fromTypeSafeDictionary.Has(entityGID.entityID) == false)
            {
                throw new ECSException("entity not found eid: ".FastConcat(entityGID.entityID).FastConcat(" group: ").FastConcat(entityGID.groupID));
            }
            fromTypeSafeDictionary.MoveEntityFromDictionaryAndEngines(entityGID, toGroupID, dictionaryOfEntities, _entityEngines);

            if (fromTypeSafeDictionary.Count == 0) //clean up
            {
                _groupedGroups[entityType].Remove(entityGID.groupID);

                //I don't remove the group if empty on purpose, in case it needs to be reused
                //however I trim it to save memory
                fromTypeSafeDictionary.Trim();
            }
        }
            public bool MoveNext()
            {
                //attention, the while is necessary to skip empty groups
                while (_db.MoveNext() == true)
                {
                    FasterDictionary<uint, ITypeSafeDictionary>.KeyValuePairFast group = _db.Current;
                    ITypeSafeDictionary<T1> typeSafeDictionary = @group.Value as ITypeSafeDictionary<T1>;
                    
                    if (typeSafeDictionary.count == 0) continue;

                    _array.collection = new EntityCollection<T1>(typeSafeDictionary.GetValues(out var count), count);
                    _array.@group = new ExclusiveGroupStruct(group.Key);

                    return true;
                }

                return false;
            }
예제 #19
0
            public void SwapEntitiesInGroup
                (ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID, [CallerMemberName] string caller = null)
            {
                if (_enginesRoot.Target._groupEntityComponentsDB.TryGetValue(
                        fromGroupID.group
                        , out FasterDictionary <RefWrapperType, ITypeSafeDictionary> entitiesInGroupPerType) == true)
                {
#if DEBUG && !PROFILE_SVELTO
                    ITypeSafeDictionary dictionary = entitiesInGroupPerType.unsafeValues[0];

                    dictionary.KeysEvaluator((key) =>
                    {
                        _enginesRoot.Target.CheckRemoveEntityID(new EGID(key, fromGroupID), null, caller);
                        _enginesRoot.Target.CheckAddEntityID(new EGID(key, toGroupID), null, caller);
                    });
#endif
                    _enginesRoot.Target.QueueSwapGroupOperation(fromGroupID, toGroupID, caller);
                }
            }
예제 #20
0
        public void FillWithIndexedEntityViews(ITypeSafeDictionary entityViews)
        {
            int count;
            var buffer = (entityViews as TypeSafeDictionary <TValue>).GetFasterValuesBuffer(out count);

            try
            {
                for (var i = 0; i < count; i++)
                {
                    var entityView = buffer[i];

                    Add(entityView.ID.entityID, entityView);
                }
            }
            catch (Exception e)
            {
                throw new TypeSafeDictionaryException(e);
            }
        }
예제 #21
0
        public void FillWithIndexedEntities(ITypeSafeDictionary entitiesToSubmit)
        {
            var buffer = (entitiesToSubmit as TypeSafeDictionary <TValue>).GetValuesArray(out var count);

            for (var i = 0; i < count; i++)
            {
                try
                {
//                    buffer[i].ID = EGID.UPDATE_REAL_ID(buffer[i].ID, entityCount);

                    Add(buffer[i].ID.entityID, ref buffer[i]);
                }
                catch (Exception e)
                {
                    throw new TypeSafeDictionaryException(
                              "trying to add an EntityView with the same ID more than once Entity: "
                              .FastConcat(typeof(TValue).ToString()).FastConcat("id ").FastConcat(buffer[i].ID.entityID), e);
                }
            }
        }
        void CopyEntityToDictionary(EGID entityGID, EGID toEntityGID,
                                    FasterDictionary <RefWrapper <Type>, ITypeSafeDictionary> fromGroup,
                                    FasterDictionary <RefWrapper <Type>, ITypeSafeDictionary> toGroup,
                                    Type entityViewType)
        {
            var wrapper = new RefWrapper <Type>(entityViewType);

            ITypeSafeDictionary fromTypeSafeDictionary = GetTypeSafeDictionary(entityGID.groupID, fromGroup, wrapper);

#if DEBUG && !PROFILER
            if (fromTypeSafeDictionary.Has(entityGID.entityID) == false)
            {
                throw new EntityNotFoundException(entityGID, entityViewType);
            }
#endif
            ITypeSafeDictionary toEntitiesDictionary =
                GetOrCreateTypeSafeDictionary(toEntityGID.groupID, toGroup, wrapper, fromTypeSafeDictionary);

            fromTypeSafeDictionary.AddEntityToDictionary(entityGID, toEntityGID, toEntitiesDictionary);
        }
        public void FillWithIndexedEntities(ITypeSafeDictionary entities)
        {
            int count;
            var buffer = (entities as TypeSafeDictionary <TValue>).GetValuesArray(out count);

            for (var i = 0; i < count; i++)
            {
                int idEntityId = 0;
                try
                {
                    idEntityId = buffer[i].ID.entityID;

                    Add(idEntityId, ref buffer[i]);
                }
                catch (Exception e)
                {
                    throw new TypeSafeDictionaryException("trying to add an EntityView with the same ID more than once Entity: ".
                                                          FastConcat(typeof(TValue)).FastConcat("id ").FastConcat(idEntityId), e);
                }
            }
        }
        public void CopyTypeSafeDictionary(ITypeSafeDictionary entitiesToSubmit, uint groupId)
        {
            var typeSafeDictionary = (entitiesToSubmit as TypeSafeDictionary <TValue>);

            foreach (var value in typeSafeDictionary)
            {
                try
                {
                    if (HasEgid)
                    {
                        (value.Value as INeedEGID).ID = new EGID(value.Key, groupId);
                    }

                    Add(value.Key, value.Value);
                }
                catch (Exception e)
                {
                    throw new TypeSafeDictionaryException(
                              "trying to add an EntityView with the same ID more than once Entity: "
                              .FastConcat(typeof(TValue).ToString()).FastConcat("id ").FastConcat(value.Key), e);
                }
            }
        }
            public bool MoveNext()
            {
                //attention, the while is necessary to skip empty groups
                while (_db.MoveNext() == true)
                {
                    FasterDictionary<uint, ITypeSafeDictionary>.KeyValuePairFast group = _db.Current;

                    ITypeSafeDictionary<T1> typeSafeDictionary1 = @group.Value as ITypeSafeDictionary<T1>;
                    ITypeSafeDictionary<T2> typeSafeDictionary2 = @group.Value as ITypeSafeDictionary<T2>;

                    DBC.ECS.Check.Require(typeSafeDictionary1.Count != typeSafeDictionary2.Count
                                        , "entities count do not match"); 
                        
                    if (typeSafeDictionary1.Count == 0) continue;
                    
                    _array = new BT<NB<T1>, NB<T2>>()(new EntityCollection<T1>(typeSafeDictionary1.GetValuesArray(out var count), count)
                       .ToBuffer();

                    return true;
                }

                return false;
            }
예제 #26
0
        public void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, int toGroupID, ITypeSafeDictionary toGroup,
                                                       Dictionary <Type, FasterList <IHandleEntityViewEngineAbstracted> >
                                                       entityViewEnginesDB)
        {
            int count;
            var fasterValuesBuffer = GetValuesArray(out count);
            var valueIndex         = GetValueIndex(fromEntityGid.entityID);

            if (entityViewEnginesDB != null)
            {
                RemoveEntityViewFromEngines(entityViewEnginesDB, ref fasterValuesBuffer[valueIndex]);
            }

            if (toGroup != null)
            {
                var toGroupCasted = toGroup as TypeSafeDictionary <TValue>;
                fasterValuesBuffer[valueIndex].ID = new EGID(fromEntityGid.entityID, toGroupID);
                toGroupCasted.Add(fromEntityGid.entityID, ref fasterValuesBuffer[valueIndex]);

                if (entityViewEnginesDB != null)
                {
                    AddEntityViewToEngines(entityViewEnginesDB, ref toGroupCasted.GetValuesArray(out count)[toGroupCasted.GetValueIndex(fromEntityGid.entityID)]);
                }
            }

            Remove(fromEntityGid.entityID);
        }
예제 #27
0
 ITypeSafeDictionary IEntityBuilder.Preallocate(ref ITypeSafeDictionary dictionary, int size)
 {
     return(Preallocate(ref dictionary, size));
 }
예제 #28
0
 internal EGIDMapper(ExclusiveGroupStruct groupStructId, ITypeSafeDictionary <T> dic) : this()
 {
     groupID = groupStructId;
     _map    = dic;
 }
예제 #29
0
        /// <summary>
        /// Todo: it would be probably better to split even further the logic between submission and callbacks
        /// Something to do when I will optimize the callbacks
        /// </summary>
        /// <param name="profiler"></param>
        /// <param name="maxNumberOfOperations"></param>
        IEnumerator SingleSubmission(PlatformProfiler profiler, uint maxNumberOfOperations)
        {
#if UNITY_NATIVE
            NativeOperationSubmission(profiler);
#endif
            ClearChecks();

            bool entitiesAreSubmitted = false;
            uint numberOfOperations   = 0;

            if (_entitiesOperations.count > 0)
            {
                using (profiler.Sample("Remove and Swap operations"))
                {
                    _transientEntitiesOperations.FastClear();
                    _entitiesOperations.CopyValuesTo(_transientEntitiesOperations);
                    _entitiesOperations.FastClear();

                    EntitySubmitOperation[] entitiesOperations = _transientEntitiesOperations.ToArrayFast(out var count);
                    for (var i = 0; i < count; i++)
                    {
                        try
                        {
                            switch (entitiesOperations[i].type)
                            {
                            case EntitySubmitOperationType.Swap:
                                MoveEntityFromAndToEngines(entitiesOperations[i].builders,
                                                           entitiesOperations[i].fromID, entitiesOperations[i].toID);
                                break;

                            case EntitySubmitOperationType.Remove:
                                MoveEntityFromAndToEngines(entitiesOperations[i].builders,
                                                           entitiesOperations[i].fromID, null);
                                break;

                            case EntitySubmitOperationType.RemoveGroup:
                                RemoveEntitiesFromGroup(
                                    entitiesOperations[i].fromID.groupID, profiler);
                                break;

                            case EntitySubmitOperationType.SwapGroup:
                                SwapEntitiesBetweenGroups(entitiesOperations[i].fromID.groupID,
                                                          entitiesOperations[i].toID.groupID, profiler);
                                break;
                            }
                        }
                        catch
                        {
                            var str = "Crash while executing Entity Operation "
                                      .FastConcat(entitiesOperations[i].type.ToString());


                            Svelto.Console.LogError(str.FastConcat(" ")
#if DEBUG && !PROFILE_SVELTO
                                                    .FastConcat(entitiesOperations[i].trace.ToString())
#endif
                                                    );

                            throw;
                        }

                        ++numberOfOperations;

                        if ((uint)numberOfOperations >= (uint)maxNumberOfOperations)
                        {
                            yield return(null);

                            numberOfOperations = 0;
                        }
                    }
                }

                entitiesAreSubmitted = true;
            }

            _groupedEntityToAdd.Swap();

            if (_groupedEntityToAdd.otherEntitiesCreatedPerGroup.count > 0)
            {
                using (profiler.Sample("Add operations"))
                {
                    try
                    {
                        using (profiler.Sample("Add entities to database"))
                        {
                            //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
                            foreach (var groupToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
                            {
                                var groupID = groupToSubmit.Key;
                                var groupDB = GetOrCreateGroup(groupID, profiler);

                                //add the entityComponents in the group
                                foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
                                {
                                    var type = entityComponentsToSubmit.Key;
                                    var targetTypeSafeDictionary = entityComponentsToSubmit.Value;
                                    var wrapper = new RefWrapperType(type);

                                    ITypeSafeDictionary dbDic = GetOrCreateTypeSafeDictionary(groupID, groupDB, wrapper,
                                                                                              targetTypeSafeDictionary);

                                    //Fill the DB with the entity components generate this frame.
                                    dbDic.AddEntitiesFromDictionary(targetTypeSafeDictionary, groupID);
                                }
                            }
                        }

                        //then submit everything in the engines, so that the DB is up to date with all the entity components
                        //created by the entity built
                        using (profiler.Sample("Add entities to engines"))
                        {
                            foreach (var groupToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup)
                            {
                                var groupID = groupToSubmit.Key;
                                var groupDB = _groupEntityComponentsDB[groupID];
//entityComponentsToSubmit is the array of components found in the groupID per component type.
//if there are N entities to submit, and M components type to add for each entity, this foreach will run NxM times.
                                foreach (var entityComponentsToSubmit in _groupedEntityToAdd.other[groupID])
                                {
                                    var realDic = groupDB[new RefWrapperType(entityComponentsToSubmit.Key)];

                                    entityComponentsToSubmit.Value.ExecuteEnginesAddOrSwapCallbacks(_reactiveEnginesAddRemove, realDic,
                                                                                                    null, new ExclusiveGroupStruct(groupID), in profiler);

                                    numberOfOperations += entityComponentsToSubmit.Value.count;

                                    if (numberOfOperations >= maxNumberOfOperations)
                                    {
                                        yield return(null);

                                        numberOfOperations = 0;
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        using (profiler.Sample("clear double buffering"))
                        {
                            //other can be cleared now, but let's avoid deleting the dictionary every time
                            _groupedEntityToAdd.ClearOther();
                        }
                    }
                }

                entitiesAreSubmitted = true;
            }

            if (entitiesAreSubmitted)
            {
                var enginesCount = _reactiveEnginesSubmission.count;
                for (int i = 0; i < enginesCount; i++)
                {
                    _reactiveEnginesSubmission[i].EntitiesSubmitted();
                }
            }
        }
예제 #30
0
 void IEntityBuilder.MoveEntityView(EGID entityID, int toGroupID, ITypeSafeDictionary fromSafeDic, ITypeSafeDictionary toSafeDic)
 {
     MoveEntityView(entityID, toGroupID, fromSafeDic, toSafeDic);
 }