/// <summary> /// Tries to parse an asset reference in the format "GUID:Location". /// </summary> /// <param name="referenceType"></param> /// <param name="assetReferenceText">The asset reference.</param> /// <param name="assetReference">The reference.</param> /// <returns><c>true</c> if parsing was successful, <c>false</c> otherwise.</returns> public static bool TryParse(Type referenceType, string assetReferenceText, out AssetReference assetReference) { if (referenceType == null) { throw new ArgumentNullException("referenceType"); } if (assetReferenceText == null) { throw new ArgumentNullException("assetReferenceText"); } assetReference = null; Guid guid; UFile location; Guid referenceId; if (!TryParse(assetReferenceText, out referenceId, out guid, out location)) { return(false); } assetReference = New(referenceType, guid, location); if (referenceId != Guid.Empty) { IdentifiableHelper.SetId(assetReference, referenceId); } return(true); }
protected override void TransformObjectAfterRead(ref ObjectContext objectContext) { if (IsSerializingAsReference) { // Transform the deserialized reference into a fake Entity, EntityComponent, etc... // Fake objects will later be fixed later with EntityAnalysis.FixupEntityReferences() if (!objectContext.SerializerContext.IsSerializing) { var entityComponentReference = objectContext.Instance as EntityComponentReference; if (entityComponentReference != null) { var entityReference = new Entity { Id = entityComponentReference.Entity.Id }; var entityComponent = (EntityComponent)Activator.CreateInstance(entityComponentReference.ComponentType); IdentifiableHelper.SetId(entityComponent, entityComponentReference.Id); entityComponent.Entity = entityReference; objectContext.Instance = entityComponent; } else if (objectContext.Instance is EntityReference) { objectContext.Instance = new Entity { Id = ((EntityReference)objectContext.Instance).Id }; } else { base.TransformObjectAfterRead(ref objectContext); } } } }
public void TestResolveCollectionBroken() { var memberPath = new MemberPath(); memberPath.Push(MemberSubs); memberPath.Push(ListClassDesc, 0); var referenceElt = new MyClass(); IdentifiableHelper.SetId(referenceElt, Guid.NewGuid()); var reference = new MyClass { Subs = { referenceElt } }; var dual = new MyClass(); dual.Subs.Add(new MyClass()); dual.Subs.Add(new MyClass()); var resolvedPaths = memberPath.Resolve(reference, dual).ToList(); Assert.AreEqual(0, resolvedPaths.Count); memberPath = new MemberPath(); memberPath.Push(MemberSubs); memberPath.Push(ListClassDesc, 1); resolvedPaths = memberPath.Resolve(reference, dual).ToList(); Assert.AreEqual(0, resolvedPaths.Count); }
private static ModelMaterial AttachId(ModelMaterial modelMaterial) { // Compute an id for the list item based on the name of the material var materialNameKey = modelMaterial.Name; var modelMaterialId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(materialNameKey)).ToGuid(); IdentifiableHelper.SetId(modelMaterial, modelMaterialId); return(modelMaterial); }
public object GenerateProxyPart(Type partType) { var component = (EntityComponent)Activator.CreateInstance(partType); component.Entity = new Entity { Id = Entity.Id }; IdentifiableHelper.SetId(component, Id); return(component); }
public void TestHash() { var obj1 = new TestAssetClonerObject { Name = "Test1", SubObject = new TestAssetClonerObject() { Name = "Test2" }, ObjectWithAttachedReference = new TestObjectReference() }; // Create a fake reference to make sure that the attached reference will not be serialized var attachedReference = AttachedReferenceManager.GetOrCreateAttachedReference(obj1.ObjectWithAttachedReference); attachedReference.Url = "just_for_test"; attachedReference.Id = Guid.NewGuid(); // Setup some proper id on objects so serialization is stable IdentifiableHelper.SetId(obj1, new Guid("EC86143E-896F-45C5-9A4D-627317D22955")); IdentifiableHelper.SetId(obj1.SubObject, new Guid("34E160CD-1D94-468E-8BFD-F82FF96013FC")); var obj2 = (TestAssetClonerObject)AssetCloner.Clone(obj1); var hash1 = AssetHash.Compute(obj1); var hash2 = AssetHash.Compute(obj2); Assert.AreEqual(hash1, hash2); obj1.Name = "Yes"; var hash11 = AssetHash.Compute(obj1); Assert.AreNotEqual(hash11, hash2); obj1.Name = "Test1"; var hash12 = AssetHash.Compute(obj1); Assert.AreEqual(hash12, hash2); // Test the same with overrides var objDesc = TypeDescriptorFactory.Default.Find(typeof(TestAssetClonerObject)); var memberDesc = objDesc.Members.First(t => t.Name == "Name"); obj1.SetOverride(memberDesc, OverrideType.New); obj1.SubObject.SetOverride(memberDesc, OverrideType.Sealed); obj2 = (TestAssetClonerObject)AssetCloner.Clone(obj1); var hash1WithOverrides = AssetHash.Compute(obj1); var hash2WithOverrides = AssetHash.Compute(obj2); Assert.AreNotEqual(hash1, hash1WithOverrides); Assert.AreNotEqual(hash2, hash2WithOverrides); Assert.AreEqual(hash1WithOverrides, hash2WithOverrides); }
public override object ConvertFrom(ref ObjectContext objectContext, Scalar fromScalar) { Guid id; if (!Guid.TryParse(fromScalar.Value, out id)) { throw new YamlException(fromScalar.Start, fromScalar.End, $"Unable to parse id [{fromScalar.Value}]"); } var materialNull = new MaterialNull(); IdentifiableHelper.SetId(materialNull, id); return(materialNull); }
public void TestResolveComplex() { var memberPath = new MemberPath(); memberPath.Push(MemberSubs); memberPath.Push(ListClassDesc, 1); memberPath.Push(MemberSub); memberPath.Push(MemberValue); var id = Guid.NewGuid(); var referenceElt = new MyClass { Sub = new MyClass { Value = 1 } }; var dualElt1 = new MyClass { Sub = new MyClass { Value = 2 } }; var dualElt2 = new MyClass { Sub = new MyClass { Value = 3 } }; var brokenDual = new MyClass(); IdentifiableHelper.SetId(referenceElt, id); IdentifiableHelper.SetId(dualElt1, id); IdentifiableHelper.SetId(dualElt2, id); IdentifiableHelper.SetId(brokenDual, id); var reference = new MyClass { Subs = { new MyClass(), referenceElt } }; var dual = new MyClass { Subs = { new MyClass(), new MyClass(), dualElt1, brokenDual, new MyClass(), dualElt2 } }; var resolvedPaths = memberPath.Resolve(reference, dual).ToList(); Assert.AreEqual(2, resolvedPaths.Count); object value; Assert.IsTrue(resolvedPaths[0].TryGetValue(dual, out value)); Assert.AreEqual(dual.Subs[2].Sub.Value, value); Assert.IsTrue(resolvedPaths[1].TryGetValue(dual, out value)); Assert.AreEqual(dual.Subs[5].Sub.Value, value); }
public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar) { AssetReference assetReference; Guid referenceId; if (!AssetReference.TryParse(fromScalar.Value, out assetReference, out referenceId)) { throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value)); } if (referenceId != Guid.Empty) { IdentifiableHelper.SetId(assetReference, referenceId); } return(assetReference); }
private static AssetItem ImportSkeleton(List <AssetItem> assetReferences, UFile assetSource, UFile localPath, EntityInfo entityInfo) { var asset = new SkeletonAsset { Source = assetSource }; if (entityInfo.Nodes != null) { for (int i = 0; i < entityInfo.Nodes.Count; i++) { var node = entityInfo.Nodes[i]; var nodeInfo = new NodeInformation(node.Name, node.Depth, node.Preserve); // Try to keep identifier id consistent // TODO: We might remove this as we don't expect Skeleton asset to be inherited, but they could int sameNameAndDepthCount = 0; for (int j = 0; j < i; j++) { var againstNode = entityInfo.Nodes[i]; // If we found a node with the same name and depth, we use a increment a counter if (againstNode.Name == node.Name && againstNode.Depth == node.Depth) { sameNameAndDepthCount++; } } var nodeNameKey = nodeInfo.Name + nodeInfo.Depth + ((sameNameAndDepthCount > 0) ? "_" + sameNameAndDepthCount : string.Empty); var nodeId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(nodeNameKey)).ToGuid(); IdentifiableHelper.SetId(nodeInfo, nodeId); asset.Nodes.Add(nodeInfo); } } if (entityInfo.AnimationNodes != null && entityInfo.AnimationNodes.Count > 0) { asset.PreserveNodes(entityInfo.AnimationNodes); } var skeletonUrl = new UFile(localPath.GetFileName() + " Skeleton"); var assetItem = new AssetItem(skeletonUrl, asset); assetReferences.Add(assetItem); return(assetItem); }
public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar) { AssetId guid; UFile location; Guid referenceId; if (!AssetReference.TryParse(fromScalar.Value, out guid, out location, out referenceId)) { throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value)); } var instance = AttachedReferenceManager.CreateProxyObject(context.Descriptor.Type, guid, location); if (referenceId != Guid.Empty) { IdentifiableHelper.SetId(instance, referenceId); } return(instance); }
/// <summary> /// Tries to parse a package reference in the format {guid:location}. /// </summary> /// <param name="packageReferenceAsText">The package reference as text.</param> /// <param name="packageReference">The package reference.</param> /// <returns><c>true</c> if the package reference is a valid reference, <c>false</c> otherwise.</returns> public static bool TryParse(string packageReferenceAsText, out PackageReference packageReference) { Guid id; UFile location; packageReference = null; Guid referenceId; if (AssetReference.TryParse(packageReferenceAsText, out referenceId, out id, out location)) { packageReference = new PackageReference(id, location); if (referenceId != Guid.Empty) { IdentifiableHelper.SetId(packageReference, referenceId); } return(true); } return(false); }
public override void Serialize(ref MaterialNull obj, ArchiveMode mode, SerializationStream stream) { if (stream.Context.SerializerSelector.HasProfile("AssetClone")) { // At design time, when performing a clone, we keep the associated id of this instance. if (mode == ArchiveMode.Serialize) { var id = IdentifiableHelper.GetId(obj); stream.Write(id); } else { var id = stream.Read <Guid>(); obj = new MaterialNull(); IdentifiableHelper.SetId(obj, id); } } else { // For runtime serialization, a MaterialNull becomes null obj = null; } }
public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar) { Guid guid; UFile location; Guid referenceId; if (!AssetReference.TryParse(fromScalar.Value, out referenceId, out guid, out location)) { throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value)); } var instance = AttachedReferenceManager.CreateSerializableVersion(context.Descriptor.Type, guid, location); // If the referenceId is empty, force its creation, else attach it to the reference if (referenceId == Guid.Empty) { IdentifiableHelper.GetId(instance); } else { IdentifiableHelper.SetId(instance, referenceId); } return(instance); }
public override void Set(object thisObject, object value) { IdentifiableHelper.SetId(thisObject, (Guid)value); }
public override void VisitArrayItem(Array array, ArrayDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor) { base.VisitArrayItem(array, descriptor, index, item, itemDescriptor); var assetReference = item as AssetReference; var assetBase = item as AssetBase; var attachedReference = AttachedReferenceManager.GetAttachedReference(item); if (assetReference != null) { AddLink(item, (guid, location) => { var newValue = AssetReference.New(descriptor.ElementType, guid ?? assetReference.Id, location); array.SetValue(newValue, index); return(newValue); }); } else if (assetBase != null) { AddLink(item, (guid, location) => { var newValue = new AssetBase(location, assetBase.Asset); array.SetValue(newValue, index); return(newValue); }); } else if (attachedReference != null) { AddLink(attachedReference, (guid, location) => { object newValue = guid.HasValue && guid.Value != Guid.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ElementType, guid.Value, location) : null; if (newValue != null) { IdentifiableHelper.SetId(newValue, IdentifiableHelper.GetId(item)); } array.SetValue(newValue, index); return(newValue); }); } else if (item is UFile) { AddLink(item, (guid, location) => { var newValue = new UFile(location); array.SetValue(newValue, index); return(newValue); }); } else if (item is UDirectory) { AddLink(item, (guid, location) => { var newValue = new UFile(location); array.SetValue(newValue, index); return(newValue); }); } }
public override void VisitCollectionItem(IEnumerable collection, CollectionDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor) { base.VisitCollectionItem(collection, descriptor, index, item, itemDescriptor); var assetReference = item as AssetReference; var assetBase = item as AssetBase; var attachedReference = AttachedReferenceManager.GetAttachedReference(item); // We cannot set links if we do not have indexer accessor if (!descriptor.HasIndexerAccessors) { return; } if (assetReference != null) { AddLink(assetReference, (guid, location) => { var link = AssetReference.New(descriptor.ElementType, guid ?? assetReference.Id, location); descriptor.SetValue(collection, index, link); return(link); }); } else if (assetBase != null) { AddLink(assetBase, (guid, location) => { var link = new AssetBase(location, assetBase.Asset); descriptor.SetValue(collection, index, link); return(link); }); } else if (attachedReference != null) { AddLink(attachedReference, (guid, location) => { var link = guid.HasValue && guid.Value != Guid.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ElementType, guid.Value, location) : null; if (link != null) { IdentifiableHelper.SetId(link, IdentifiableHelper.GetId(item)); } descriptor.SetValue(collection, index, link); return(link); }); } else if (item is UFile) { AddLink(item, (guid, location) => { var link = new UFile(location); descriptor.SetValue(collection, index, link); return(link); }); } else if (item is UDirectory) { AddLink(item, (guid, location) => { var link = new UDirectory(location); descriptor.SetValue(collection, index, link); return(link); }); } }
public override void VisitDictionaryKeyValue(object dictionaryObj, DictionaryDescriptor descriptor, object key, ITypeDescriptor keyDescriptor, object value, ITypeDescriptor valueDescriptor) { base.VisitDictionaryKeyValue(dictionaryObj, descriptor, key, keyDescriptor, value, valueDescriptor); var assetReference = value as AssetReference; var assetBase = value as AssetBase; var attachedReference = AttachedReferenceManager.GetAttachedReference(value); if (assetReference != null) { AddLink(assetReference, (guid, location) => { var newValue = AssetReference.New(descriptor.ValueType, guid ?? assetReference.Id, location); descriptor.SetValue(dictionaryObj, key, newValue); return(newValue); }); } else if (assetBase != null) { AddLink(assetBase, (guid, location) => { var newValue = new AssetBase(location, assetBase.Asset); descriptor.SetValue(dictionaryObj, key, newValue); return(newValue); }); } else if (attachedReference != null) { AddLink(attachedReference, (guid, location) => { object newValue = guid.HasValue && guid.Value != Guid.Empty ? AttachedReferenceManager.CreateProxyObject(descriptor.ValueType, guid.Value, location) : null; if (newValue != null) { IdentifiableHelper.SetId(newValue, IdentifiableHelper.GetId(value)); } descriptor.SetValue(dictionaryObj, key, newValue); return(newValue); }); } else if (value is UFile) { AddLink(value, (guid, location) => { var newValue = new UFile(location); descriptor.SetValue(dictionaryObj, key, newValue); return(newValue); }); } else if (value is UDirectory) { AddLink(value, (guid, location) => { var newValue = new UDirectory(location); descriptor.SetValue(dictionaryObj, key, newValue); return(newValue); }); } }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { base.VisitObjectMember(container, containerDescriptor, member, value); var assetReference = value as AssetReference; var assetBase = value as AssetBase; var attachedReference = AttachedReferenceManager.GetAttachedReference(value); if (assetReference != null) { AddLink(assetReference, (guid, location) => { var newValue = AssetReference.New(member.Type, guid ?? assetReference.Id, location); member.Set(container, newValue); return(newValue); }); } else if (assetBase != null) { AddLink(assetBase, (guid, location) => { var newValue = new AssetBase(location, assetBase.Asset); member.Set(container, newValue); return(newValue); }); } else if (attachedReference != null) { AddLink(attachedReference, (guid, location) => { object newValue = guid.HasValue && guid.Value != Guid.Empty ? AttachedReferenceManager.CreateProxyObject(member.Type, guid.Value, location) : null; if (newValue != null) { IdentifiableHelper.SetId(newValue, IdentifiableHelper.GetId(value)); } member.Set(container, newValue); return(newValue); }); } else if (value is UFile) { AddLink(value, (guid, location) => { var newValue = new UFile(location); member.Set(container, newValue); return(newValue); }); } else if (value is UDirectory) { AddLink(value, (guid, location) => { var newValue = new UDirectory(location); member.Set(container, newValue); return(newValue); }); } }
public void Test() { var prefab = new PrefabAsset(); var modelComponent = new ModelComponent(); var entity = new Entity() { modelComponent }; prefab.Hierarchy.Parts.Add(new EntityDesign(entity)); prefab.Hierarchy.RootPartIds.Add(entity.Id); var material1 = new MaterialNull(); IdentifiableHelper.SetId(material1, new Guid("39E2B226-8752-4678-8E93-76FFBFBA337B")); var material2 = new MaterialNull(); IdentifiableHelper.SetId(material2, new Guid("CC4F1B31-FBB7-4360-A3E7-060BDFDA0695")); modelComponent.Materials.Add(material1); modelComponent.Materials.Add(material2); Action <PrefabAsset> checkPrefab = (newPrefab) => { var previousEntityDesign = newPrefab.Hierarchy.Parts.FirstOrDefault(); Assert.NotNull(previousEntityDesign); var previousEntity = previousEntityDesign.Entity; var component = previousEntity.Get <ModelComponent>(); Assert.NotNull(component); Assert.AreEqual(2, component.Materials.Count); var newMaterial1 = component.Materials[0]; Assert.AreEqual(IdentifiableHelper.GetId(material1), IdentifiableHelper.GetId(newMaterial1)); var newMaterial2 = component.Materials[1]; Assert.AreEqual(IdentifiableHelper.GetId(material2), IdentifiableHelper.GetId(newMaterial2)); }; // Test yaml serialization { using (var stream = new MemoryStream()) { AssetSerializer.Save(stream, prefab); stream.Position = 0; var serializedVersion = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(serializedVersion); stream.Position = 0; var newPrefab = (PrefabAsset)AssetSerializer.Load(stream, "myentity"); checkPrefab(newPrefab); } } // Test cloning var newPrefabClone = (PrefabAsset)AssetCloner.Clone(prefab); checkPrefab(newPrefabClone); // Test runtime serialization (runtime serialization is removing MaterialNull and replacing it by a null) { var stream = new MemoryStream(); var writer = new BinarySerializationWriter(stream) { Context = { SerializerSelector = SerializerSelector.AssetWithReuse } }; writer.SerializeExtended(entity, ArchiveMode.Serialize); writer.Flush(); stream.Position = 0; var reader = new BinarySerializationReader(stream) { Context = { SerializerSelector = SerializerSelector.AssetWithReuse } }; Entity newEntity = null; reader.SerializeExtended(ref newEntity, ArchiveMode.Deserialize); Assert.NotNull(newEntity); var component = newEntity.Get <ModelComponent>(); Assert.NotNull(component); Assert.AreEqual(2, component.Materials.Count); Assert.Null(component.Materials[0]); Assert.Null(component.Materials[1]); } }