static void BuildEntity(EGID entityID, FasterDictionary <RefWrapperType, ITypeSafeDictionary> group , IComponentBuilder componentBuilder, IEnumerable <object> implementors) { var entityComponentType = componentBuilder.GetEntityComponentType(); var safeDictionary = group.GetOrCreate(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); }
internal static void SetEntityViewComponentImplementors <T>(this IComponentBuilder componentBuilder, ref T entityComponent, IEnumerable <object> implementors, ComponentBuilder <T> .EntityViewComponentCache localCache) where T : struct, IBaseEntityComponent { DBC.ECS.Check.Require(implementors != null, NULL_IMPLEMENTOR_ERROR.FastConcat(" entityComponent ", componentBuilder.GetEntityComponentType().ToString())); var cachedTypeInterfaces = localCache.cachedTypes; var implementorsByType = localCache.implementorsByType; var entityComponentBlazingFastReflection = localCache.cachedFields; foreach (var implementor in implementors) { DBC.ECS.Check.Require(implementor != null, "invalid null implementor used to build an entity"); { var type = implementor.GetType(); //fetch all the interfaces that the implementor implements if (cachedTypeInterfaces.TryGetValue(type, out var interfaces) == false) { interfaces = cachedTypeInterfaces[type] = type.GetInterfacesEx(); } for (var iindex = 0; iindex < interfaces.Length; iindex++) { var componentType = interfaces[iindex]; //an implementor can implement multiple interfaces, so for each interface we reference //the implementation object. Multiple entity view component fields can then be implemented //by the same implementor #if DEBUG && !PROFILE_SVELTO if (implementorsByType.TryGetValue(componentType, out var implementorData)) { implementorData.numberOfImplementations++; implementorsByType[componentType] = implementorData; } else { implementorsByType[componentType] = new ECSTuple <object, int>(implementor, 1); } #else implementorsByType[componentType] = implementor; #endif } } } //efficient way to collect the fields of every EntityComponentType var setters = FasterList <KeyValuePair <Type, FastInvokeActionCast <T> > > .NoVirt.ToArrayFast( entityComponentBlazingFastReflection, out var count); for (var i = 0; i < count; i++) { var fieldSetter = setters[i]; var fieldType = fieldSetter.Key; #if DEBUG && !PROFILE_SVELTO ECSTuple <object, int> implementor; #else object implementor; #endif if (implementorsByType.TryGetValue(fieldType, out implementor) == false) { var e = new ECSException(NOT_FOUND_EXCEPTION + " Component Type: " + fieldType.Name + " - EntityComponent: " + componentBuilder.GetEntityComponentType().Name); throw e; } #if DEBUG && !PROFILE_SVELTO if (implementor.numberOfImplementations > 1) { throw new ECSException(DUPLICATE_IMPLEMENTOR_ERROR.FastConcat( "Component Type: ", fieldType.Name, " implementor: ", implementor.instance.ToString()) + " - EntityComponent: " + componentBuilder.GetEntityComponentType().Name); } #endif #if DEBUG && !PROFILE_SVELTO fieldSetter.Value(ref entityComponent, implementor.instance); #else fieldSetter.Value(ref entityComponent, implementor); #endif } implementorsByType.Clear(); }