internal async Task Relink(DocumentModel model, DocumentModelData newData) { bool newDataLocked = false, representationLocked = false; ModelRepresentation representation = null; var repType = model.RepresentationType; ModelRepresentation modelRepresentationToDispose = null; var modelsToNotify = new List <DocumentModel> (); await dataLock.WaitAsync(); try { representations.TryGetValue(repType, out representation); await representation.WaitHandle.WaitAsync(); representationLocked = true; linkedModels = linkedModels.Remove(model); var modelsForRep = linkedModels.Where(m => m.RepresentationType == repType).ToList(); if (modelsForRep.Count > 0) { // If there is more than one model using this representation then the representation // has to be cloned, since it can't be shared anymore var representationCopy = (ModelRepresentation)Activator.CreateInstance(representation.GetType()); await representationCopy.InternalCopyFrom(representation); representationCopy.DocumentModelData = this; representations [repType] = representationCopy; foreach (var m in modelsForRep) { modelsToNotify.Add(m); } } else { await RemoveRepresentation(repType, representation); } if (newData != null) { await newData.dataLock.WaitAsync(); newDataLocked = true; // If there are other models using the same representation, we'll have to notify them that // the representation has changed if (newData.representations.TryGetValue(repType, out modelRepresentationToDispose)) { modelsToNotify.AddRange(newData.linkedModels.Where(m => m.RepresentationType == repType)); } newData.linkedModels = newData.linkedModels.Add(model); model.Data = newData; newData.representations [repType] = representation; representation.DocumentModelData = newData; // Register that this new representation is the latest version. // If there are other representations, they will get the new data after a Synchronize call. newData.NotifyChanged(representation); } } finally { dataLock.Release(); if (representationLocked) { representation.WaitHandle.Release(); } if (newDataLocked) { newData.dataLock.Release(); } } foreach (var m in modelsToNotify) { m.RaiseRepresentationChangeEvent().Ignore(); } if (modelRepresentationToDispose != null) { modelRepresentationToDispose.OnDispose().Ignore(); } }
public void LinkNewNoLock(DocumentModel model) { linkedModels = linkedModels.Add(model); model.Data = this; }