private void MapEntities <T>(AssetCompositeHierarchyData <EntityDesign, Entity> hierarchyData, Dictionary <GroupPartKey, T> entities, Guid?instancePartIdArg = null) where T : EntityEntry { if (hierarchyData == null) { return; } // Important, if the hierarchy is coming from a part, we need to clone it entirely // and associate correctly the instancePartId with each entities that it is composed of. if (instancePartIdArg.HasValue) { hierarchyData = (AssetCompositeHierarchyData <EntityDesign, Entity>)AssetCloner.Clone(hierarchyData); } foreach (var entityDesign in hierarchyData.Parts) { if (instancePartIdArg.HasValue) { entityDesign.BasePartInstanceId = instancePartIdArg; } var key = new GroupPartKey(instancePartIdArg, entityDesign.Entity.Id); if (entities.ContainsKey(key)) { continue; } EntityEntry remap; if (typeof(T) == typeof(NewEntityEntry)) { remap = new NewEntityEntry(entityDesign, hierarchyData, entities.Count); } else if (typeof(T) == typeof(BaseEntityEntry)) { remap = new BaseEntityEntry(entityDesign, hierarchyData, entities.Count); } else { throw new ArgumentException($"Invalid type [{typeof(T)}]. Expecting concrete type NewEntityEntry or BaseEntityEntry"); } entities[key] = (T)remap; } }
private List <Guid> MergeHierarchyByLevel(List <Guid> entityIds) { var nextEntityIds = new List <Guid>(); foreach (var entityId in entityIds) { var remap = newEntities[new GroupPartKey(null, entityId)]; var entity = remap.EntityDesign.Entity; // If we have a base/newbase, we can 3-ways merge lists if (remap.Base != null) { // Build a list of Entities Ids for the BaseEntity.Transform.Children remapped to the new entities (using the BasePartInstanceId of the entity being processed) var baseChildrenId = new List <Guid>(); var basePartInstanceId = remap.EntityDesign.BasePartInstanceId; if (remap.Base.Children != null) { foreach (var transformComponent in remap.Base.Children) { BaseEntityEntry baseEntry; if (baseEntities.TryGetValue(new GroupPartKey(basePartInstanceId, transformComponent.Entity.Id), out baseEntry) && baseEntry.NewEntity != null) { baseChildrenId.Add(baseEntry.NewEntity.EntityDesign.Entity.Id); } } } // List of Entity ids of the NewEntity.Transform.Children var currentChildrenIds = new List <Guid>(); if (remap.Children != null) { foreach (var transformComponent in remap.Children) { currentChildrenIds.Add(transformComponent.Entity.Id); } } // Build a list of Entities Ids for the NewBaseEntity.Transform.Children remapped to the new entities (using the BasePartInstanceId of the entity being processed) var newBaseChildrenIds = new List <Guid>(); if (remap.NewBase?.Children != null) { foreach (var transformComponent in remap.NewBase.Children) { BaseEntityEntry baseEntry = null; if (newBaseEntities.TryGetValue(new GroupPartKey(basePartInstanceId, transformComponent.Entity.Id), out baseEntry) && baseEntry.NewEntity != null) { newBaseChildrenIds.Add(baseEntry.NewEntity.EntityDesign.Entity.Id); } } } // Perform a merge only if it is needed if (currentChildrenIds.Count > 0 && (baseChildrenId.Count > 0 || newBaseChildrenIds.Count > 0)) { // Perform a merge of a IDs list var diff = new AssetDiff(baseChildrenId, currentChildrenIds, newBaseChildrenIds) { UseOverrideMode = true, }; var localResult = AssetMerge.Merge(diff, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1); localResult.CopyTo(result); } if (remap.Children != null) { remap.Children.Clear(); } foreach (var childId in currentChildrenIds) { NewEntityEntry newChildRemap; if (newEntities.TryGetValue(new GroupPartKey(null, childId), out newChildRemap)) { if (remap.Children == null) { remap.Children = new List <TransformComponent>(); } remap.Children.Add(newChildRemap.EntityDesign.Entity.Transform); } } } else if (remap.IsNewBase && remap.Children != null) { // If the entity is coming from NewBase, we need to transform the previous children // to the new one mapped var children = new List <TransformComponent>(remap.Children); remap.Children.Clear(); var basePartInstanceId = remap.EntityDesign.BasePartInstanceId; foreach (var transformComponent in children) { BaseEntityEntry baseToNew = null; if (newBaseEntities.TryGetValue(new GroupPartKey(basePartInstanceId, transformComponent.Entity.Id), out baseToNew) && baseToNew.NewEntity != null) { remap.Children.Add(baseToNew.NewEntity.EntityDesign.Entity.Transform); } } } // Popup the children remap.PopChildren(); // For each child, add them to the list of entities in hierarchy and that we will // process them in the next round for (int i = 0; i < entity.Transform.Children.Count; i++) { var transformChild = entity.Transform.Children[i]; var subEntityId = transformChild.Entity.Id; if (entitiesInHierarchy.Add(subEntityId)) { nextEntityIds.Add(subEntityId); } else { // The entity was already in the hierarchy, so we remove them from this one. entity.Transform.Children.RemoveAt(i); i--; } } } return(nextEntityIds); }