private void SerializeObject(Queue <SerializeOperation> serializeOperations, string url, object obj, bool publicReference) { // Don't create context in case we don't want to serialize referenced objects //if (!SerializeReferencedObjects && obj != RootObject) // return null; // Already saved? // TODO: Ref counting? Should we change it on save? Probably depends if we cache or not. if (LoadedAssetReferences.ContainsKey(obj)) { return; } var serializer = Serializer.GetSerializer(null, obj.GetType()); if (serializer == null) { throw new InvalidOperationException(string.Format("Content serializer for {0} could not be found.", obj.GetType())); } var contentSerializerContext = new ContentSerializerContext(url, ArchiveMode.Serialize, this); using (var stream = FileProvider.OpenStream(url, VirtualFileMode.Create, VirtualFileAccess.Write)) { var streamWriter = new BinarySerializationWriter(stream); PrepareSerializerContext(contentSerializerContext, streamWriter.Context); ChunkHeader header = null; // Allocate space in the stream, and also include header version in the hash computation, which is better // If serialization type is null, it means there should be no header. var serializationType = serializer.SerializationType; if (serializationType != null) { header = new ChunkHeader(); header.Type = serializer.SerializationType.AssemblyQualifiedName; header.Write(streamWriter); header.OffsetToObject = (int)streamWriter.NativeStream.Position; } contentSerializerContext.SerializeContent(streamWriter, serializer, obj); // Write references and updated header if (header != null) { header.OffsetToReferences = (int)streamWriter.NativeStream.Position; contentSerializerContext.SerializeReferences(streamWriter); // Move back to the pre-allocated header position in the steam stream.Seek(0, SeekOrigin.Begin); // Write actual header. header.Write(new BinarySerializationWriter(stream)); } } var assetReference = new Reference(url, publicReference); SetAssetObject(assetReference, obj); // Process content references // TODO: Should we work at ChunkReference level? foreach (var contentReference in contentSerializerContext.ContentReferences) { if (contentReference.ObjectValue != null) { var attachedReference = AttachedReferenceManager.GetAttachedReference(contentReference.ObjectValue); if (attachedReference == null || attachedReference.IsProxy) { continue; } serializeOperations.Enqueue(new SerializeOperation(contentReference.Location, contentReference.ObjectValue, false)); } } }