public void TestEntitySerialization() { var entityAsset = new EntityAsset(); var entity1 = new Entity { Id = Guid.NewGuid() }; var entity2 = new Entity { Id = Guid.NewGuid() }; entity1.Transform.Children.Add(entity2.Transform); entityAsset.Hierarchy.Entities.Add(entity1); entityAsset.Hierarchy.Entities.Add(entity2); using (var stream = new MemoryStream()) { AssetSerializer.Save(stream, entityAsset); stream.Position = 0; var serializedVersion = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(serializedVersion); stream.Position = 0; var entityAsset2 = AssetSerializer.Load(stream, "xkentity"); } }
public static void UpdateScene(EntityAsset source, EntityAsset dest, Guid destRootEntityId) { if (source == null) { throw new ArgumentNullException("source"); } if (dest == null) { throw new ArgumentNullException("dest"); } EntityBase entityBase; if (!dest.AssetBases.TryGetValue(destRootEntityId, out entityBase)) { throw new InvalidOperationException("This entity base was not found with given Id."); } var entityBaseAsset = (EntityAsset)entityBase.Base.Asset; // Extract the scene starting from given root var clonedSource = ExtractSceneClone(source, entityBase.SourceRoot); // Process entities in mapping var entitiesDiff3 = new List <EntityDiff3>(); var entitiesSourceId = new HashSet <Guid>(entityBase.IdMapping.Values); var oppositeMapping = entityBase.IdMapping.ToDictionary(x => x.Value, x => x.Key); foreach (var entityIdEntry in entityBase.IdMapping) { var entityDiff3 = new EntityDiff3(); var destEntityId = entityIdEntry.Key; var sourceEntityId = entityIdEntry.Value; // Get entity in dest asset (if not there anymore, we can simply skip them, they have been deleted so they can be ignored from future merges) if (!dest.Hierarchy.Entities.TryGetValue(destEntityId, out entityDiff3.Asset1)) { continue; } // Get entity in updated asset clonedSource.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Asset2); // Get entity in base (previous import) entityBaseAsset.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Base); entitiesDiff3.Add(entityDiff3); } // Merge foreach (var entityDiff3 in entitiesDiff3) { throw new NotImplementedException(); //entityDiff3.MergeResult = AssetMerge.Merge(entityDiff3.Base, entityDiff3.Asset1, entityDiff3.Asset2, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1); // TODO: Proper logging and error recovery if (entityDiff3.MergeResult.HasErrors) { throw new InvalidOperationException("Merge error"); } } // We gather entities that were added in our source since last import // Note: We only cares about the ones that are in source but not in base -- everything else should be in entityBase.IdMapping // (otherwise it means entity has been deleted already in dest and/or source, so merge is deleted) var sourceExtraIds = new HashSet <Guid>(clonedSource.Hierarchy.Entities.Select(x => x.Entity.Id)); // Everything in source, sourceExtraIds.ExceptWith(entityBaseAsset.Hierarchy.Entities.Select(x => x.Entity.Id)); // but not in base, sourceExtraIds.ExceptWith(entitiesSourceId); // and not in entityBase.IdMapping... foreach (var sourceEntityId in sourceExtraIds) { var entityDiff3 = new EntityDiff3(); // Get entity in updated asset clonedSource.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Asset2); // Add it in our new entity, if possible at the same location var asset = entityDiff3.Asset2; var parentSourceEntity = FindParent(clonedSource.Hierarchy, entityDiff3.Asset2.Entity); Guid parentDestEntityId; if (!oppositeMapping.TryGetValue(parentSourceEntity.Id, out parentDestEntityId)) { continue; } } // Rebuild tree foreach (var entityDiff3 in entitiesDiff3) { // TODO: Try to propagate tree changes (it's not a big deal if we fail, but try to do it as good as possible) } }
public static void UpdateScene(EntityAsset source, EntityAsset dest, Guid destRootEntityId) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); EntityBase entityBase; if (!dest.AssetBases.TryGetValue(destRootEntityId, out entityBase)) throw new InvalidOperationException("This entity base was not found with given Id."); var entityBaseAsset = (EntityAsset)entityBase.Base.Asset; // Extract the scene starting from given root var clonedSource = ExtractSceneClone(source, entityBase.SourceRoot); // Process entities in mapping var entitiesDiff3 = new List<EntityDiff3>(); var entitiesSourceId = new HashSet<Guid>(entityBase.IdMapping.Values); var oppositeMapping = entityBase.IdMapping.ToDictionary(x => x.Value, x => x.Key); foreach (var entityIdEntry in entityBase.IdMapping) { var entityDiff3 = new EntityDiff3(); var destEntityId = entityIdEntry.Key; var sourceEntityId = entityIdEntry.Value; // Get entity in dest asset (if not there anymore, we can simply skip them, they have been deleted so they can be ignored from future merges) if (!dest.Hierarchy.Entities.TryGetValue(destEntityId, out entityDiff3.Asset1)) continue; // Get entity in updated asset clonedSource.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Asset2); // Get entity in base (previous import) entityBaseAsset.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Base); entitiesDiff3.Add(entityDiff3); } // Merge foreach (var entityDiff3 in entitiesDiff3) { throw new NotImplementedException(); //entityDiff3.MergeResult = AssetMerge.Merge(entityDiff3.Base, entityDiff3.Asset1, entityDiff3.Asset2, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1); // TODO: Proper logging and error recovery if (entityDiff3.MergeResult.HasErrors) throw new InvalidOperationException("Merge error"); } // We gather entities that were added in our source since last import // Note: We only cares about the ones that are in source but not in base -- everything else should be in entityBase.IdMapping // (otherwise it means entity has been deleted already in dest and/or source, so merge is deleted) var sourceExtraIds = new HashSet<Guid>(clonedSource.Hierarchy.Entities.Select(x => x.Entity.Id)); // Everything in source, sourceExtraIds.ExceptWith(entityBaseAsset.Hierarchy.Entities.Select(x => x.Entity.Id)); // but not in base, sourceExtraIds.ExceptWith(entitiesSourceId); // and not in entityBase.IdMapping... foreach (var sourceEntityId in sourceExtraIds) { var entityDiff3 = new EntityDiff3(); // Get entity in updated asset clonedSource.Hierarchy.Entities.TryGetValue(sourceEntityId, out entityDiff3.Asset2); // Add it in our new entity, if possible at the same location var asset = entityDiff3.Asset2; var parentSourceEntity = FindParent(clonedSource.Hierarchy, entityDiff3.Asset2.Entity); Guid parentDestEntityId; if (!oppositeMapping.TryGetValue(parentSourceEntity.Id, out parentDestEntityId)) continue; } // Rebuild tree foreach (var entityDiff3 in entitiesDiff3) { // TODO: Try to propagate tree changes (it's not a big deal if we fail, but try to do it as good as possible) } }