private bool HasValidReferencesForListItem(ReferencesTable referencesTable, string uniqueID, HashSet <string> _objectsToBeValidatedAfterDisposeHashSet) { var isValid = false; for (int i = referencesTable.References.Count - 1; i >= 0; i--) { var reference = referencesTable.References[i]; bool isPage = UniqueIDGenerator.IsPage(reference.TargetUniqueID); if (isPage) { var page = reference.Target as Page; string pageParentUniqueID = GetPageParentUniqueID(page); //the reference is valid if and only if the list is not in elements to remove, and if the list is allbranchesattached. if (!StateManager.Current.IsInElementsToRemove(pageParentUniqueID) && StateManager.AllBranchesAttached(pageParentUniqueID)) { isValid = true; } } else if (!StateManager.Current.IsInElementsToRemove(reference.TargetUniqueID)) { //if the reference is not a page, this means it is a pointer pointing to the list item // and this pointer is not in elementsToRemove Collection //so this item has valid reference yet. isValid = true; _objectsToBeValidatedAfterDisposeHashSet.Add(uniqueID); } } return(isValid); }
/// <summary> /// Creates a reference table to an Object. /// </summary> /// <param name="valueObject"></param> /// <returns></returns> private ReferencesTable CreateObjectReferencesTable(IStateObject valueObject) { var new_relativeUid = UniqueIDGenerator.GetReferenceTableRelativeUniqueID(valueObject.UniqueID); LazyBehaviours.AddDependent(valueObject, UniqueIDGenerator.REFTABLEPrefix); ReferencesTable referencesTable = new ReferencesTable(); referencesTable.UniqueID = new_relativeUid; referencesTable.IsReferencedObjectAnIDisposableDependencyControl = valueObject is IDisposableDependencyControl; if (StateManager.AllBranchesAttached(valueObject)) { //at this point we have a new pointer with an attached parent //which means that it was born on the temp stateManager //we cannot just do a switchunique ids because switching //is only on the stateManager level //we need to promote it from temp to StateManager //to make sure that it will be persisted _stateManager.AddNewAttachedObject(referencesTable); } else { //at this point we have a new pointer with an UNATTACHED parent //which means both the parent and the pointer are on the temp stateManager //we need to switchunique ids because //they are at the stateManager level //if the parent is promoted so will be the pointer _stateManager.AddNewTemporaryObject(referencesTable); } return(referencesTable); }
private bool TransferValueToReference(string branchRemoved, ReferencesTable referencesTable, IStateObject elementToAdoptObj = null, bool isDispose = false, IFormBaseViewModel formBaseViewModel = null) { if (isDispose && referencesTable.IsReferencedObjectAnIDisposableDependencyControl) { return(false); } //If the elementToAdopt was not sent as a parameter let's calculate it. if (elementToAdoptObj == null) { elementToAdoptObj = referencesTable.ReferencedObject; } string oldParentUniqueID = elementToAdoptObj.UniqueID; //Entire windows won't be preserved. if (elementToAdoptObj is IViewModel) { return(false); } //Let's get the reference candidate for the adoption. var reference = GetReferenceValidForAdoption(referencesTable, false); if (reference == null) { return(false); } var candidate = CalculateCandidateForAdoption(reference); //The cadidates parent was already removed...Ciao if (candidate == null) { return(false); } bool doNotRegisterIDSwitch = true; if (formBaseViewModel == null) { formBaseViewModel = ViewManager.Instance.GetTopLevelObject(elementToAdoptObj) as IFormBaseViewModel; } if (formBaseViewModel != null) { doNotRegisterIDSwitch = formBaseViewModel.IsDisposing; } if (!(elementToAdoptObj is IDisposableDependencyControl) || (!isDispose && !doNotRegisterIDSwitch)) { //The element won't belong to the parent anymore. IStateObject elementsToBeAdopted = _stateManager.DettachObject(elementToAdoptObj, !doNotRegisterIDSwitch); //We need to promote the object and attach it to the first candidate. AdoptionInformation.StaticAdopt(candidate, elementsToBeAdopted); ////Let's update all the references UpdateReferencesTables(oldParentUniqueID, elementToAdoptObj.UniqueID); //Only foreign references allowed referencesTable.RemoveReference(reference); //We move the element to a substitute parent. referencesTable.AttachedToParent = false; //We had a succesfull adoption :) return(true); } return(false); }
/// <summary> /// Let's get the reference candidate for the adoption. /// </summary> /// <param name="referencedObject"></param> /// <param name="onlyAllBranchesAttached"></param> /// <returns></returns> public IStateObject GetReferenceValidForAdoption(ReferencesTable referencesTable, bool onlyAllBranchesAttached = true, bool isHandlingOrphans = false) { IStateObject result = null; if (referencesTable != null) { IStateObject firstNonVisualParentCandidate = null;; IStateObject firstVisualParentCandidate = null; foreach (var candidate in referencesTable.References) { var parent = CalculateCandidateForAdoption(candidate.Target as IStateObject); //If the possible parent is a page, lets retrieve tha page's parent ( the list ), he will be the candidate //who will compete with other parents in the addoption process. if (isHandlingOrphans && parent is Page) { if ((parent as Page).Parent is IStateObject) { parent = (parent as Page).Parent as IStateObject; } else { parent = StateManager.Current.GetObject((parent as Page).Parent as string); } } if (parent == null) { continue; } if (!onlyAllBranchesAttached || (onlyAllBranchesAttached && StateManager.AllBranchesAttached(parent))) { var isTopModel = UniqueIDGenerator.IsRootModel(parent.UniqueID); var isTopShared = UniqueIDGenerator.IsRootSharedState(parent.UniqueID); if (isTopModel || isTopShared || parent is IModel || parent is IDependentModel || parent is IPromise) { firstNonVisualParentCandidate = parent; continue; } if (parent is IViewModel || parent is IDependentViewModel) { firstVisualParentCandidate = parent; break; } } } if (firstVisualParentCandidate != null) { result = firstVisualParentCandidate; } else if (firstNonVisualParentCandidate != null) { result = firstNonVisualParentCandidate; } } return(result); }
/// <summary> /// Gets the References table associated to an IStateObject /// </summary> /// <param name="valueObject"></param> /// <returns></returns> private ReferencesTable GetObjectReferencesTable(string uniqueID) { ReferencesTable result = null; var uniqueId = UniqueIDGenerator.GetReferenceTableRelativeUniqueID(uniqueID); var obj = _stateManager.GetObject(uniqueId); if (obj != null) { result = obj as ReferencesTable; } return(result); }