示例#1
0
 public void NotifyChanged(ModelRepresentation representation)
 {
     lock (changeLock) {
         lastChangedRepresentation     = representation;
         representation.CurrentVersion = ++changeVersion;
     }
     RaiseChangedEvent(representation.GetType());
 }
示例#2
0
            public void NotifyHasUnsavedChanges(ModelRepresentation representation)
            {
                var repType = representation.GetType();

                foreach (var m in linkedModels)
                {
                    if (m.RepresentationType == repType)
                    {
                        m.RaiseHasUnsavedChangesEvent();
                    }
                }
            }
示例#3
0
            async Task Synchronize(ModelRepresentation targetRep, bool dataLocked)
            {
                ModelRepresentation sourceModel = null;
                int currentChangeVersion;

                lock (changeLock) {
                    sourceModel          = lastChangedRepresentation;
                    currentChangeVersion = changeVersion;
                }

                if (targetRep.CurrentVersion == currentChangeVersion || sourceModel == null || sourceModel == targetRep)
                {
                    return;                     // Not changed
                }
                try {
                    // Any operation that requires the lock of several representation must take
                    // the model lock first, to avoid deadlocks
                    if (!dataLocked)
                    {
                        await dataLock.WaitAsync();

                        await targetRep.WaitHandle.WaitAsync();

                        await sourceModel.WaitHandle.WaitAsync();
                    }

                    await targetRep.InternalCopyFrom(sourceModel);
                } finally {
                    if (!dataLocked)
                    {
                        dataLock.Release();
                        targetRep.WaitHandle.Release();
                        sourceModel.WaitHandle.Release();
                    }
                }
                RaiseChangedEvent(targetRep.GetType());
            }
示例#4
0
            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();
                }
            }
示例#5
0
 protected override async Task OnCopyFrom(ModelRepresentation other)
 {
     if (other is FileModelRepresentation file)
     {
         await SetContent(file.GetContent());
     }
     else
     {
         throw new InvalidOperationException($"Can't copy data from model of type {other.GetType ()} into a model of type {GetType ()}");
     }
 }