/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { Debug.Assert(operation != null); int Index = operation.Index; Debug.Assert(Index >= 0 && Index < StateList.Count); INode ParentNode = Owner.Node; IWriteableNodeState OldChildState = StateList[Index]; INode OldNode = OldChildState.Node; IWriteableBrowsingListNodeIndex OldBrowsingIndex = (IWriteableBrowsingListNodeIndex)OldChildState.ParentIndex; RemoveFromStateList(Index); NodeTreeHelperList.ReplaceNode(ParentNode, PropertyName, Index, operation.NewNode); IWriteableBrowsingListNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(operation.NewNode, Index); IWriteablePlaceholderNodeState NewChildState = (IWriteablePlaceholderNodeState)CreateNodeState(NewBrowsingIndex); InsertInStateList(Index, NewChildState); operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState); }
/// <summary> /// Replace an existing node with a new one. /// </summary> /// <param name="inner">The inner where the node is replaced.</param> /// <param name="replaceIndex">Index for the replace operation.</param> /// <param name="nodeIndex">Index of the replacing node upon return.</param> public void Replace(IWriteableInner inner, IWriteableInsertionChildIndex replaceIndex, out IWriteableBrowsingChildIndex nodeIndex) { Contract.RequireNotNull(inner, out IWriteableInner Inner); Contract.RequireNotNull(replaceIndex, out IWriteableInsertionChildIndex ReplaceIndex); IWriteableNodeState Owner = Inner.Owner; IWriteableIndex ParentIndex = Owner.ParentIndex; Debug.Assert(Contains(ParentIndex)); Debug.Assert(IndexToState(ParentIndex) == Owner); WriteableInnerReadOnlyDictionary <string> InnerTable = Owner.InnerTable; Debug.Assert(InnerTable.ContainsKey(Inner.PropertyName)); Debug.Assert(InnerTable[Inner.PropertyName] == Inner); IndexToPositionAndNode(ReplaceIndex, out int BlockIndex, out int Index, out bool ClearNode, out Node NewNode); Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoReplace(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoReplace(operation); IWriteableReplaceOperation Operation = CreateReplaceOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, ClearNode, NewNode, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); nodeIndex = Operation.NewBrowsingIndex; }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { int BlockIndex = operation.BlockIndex; Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count); IWriteableBlockState BlockState = (IWriteableBlockState)BlockStateList[BlockIndex]; int Index = operation.Index; Debug.Assert(Index >= 0 && Index < BlockState.StateList.Count); IBlock ChildBlock = BlockState.ChildBlock; Node ParentNode = Owner.Node; IWriteableNodeState OldChildState = (IWriteableNodeState)BlockState.StateList[Index]; Node OldNode = OldChildState.Node; IWriteableBrowsingBlockNodeIndex OldBrowsingIndex = (IWriteableBrowsingBlockNodeIndex)OldChildState.ParentIndex; BlockState.Remove(OldBrowsingIndex, Index); NodeTreeHelperBlockList.ReplaceInBlock(ChildBlock, Index, operation.NewNode); IWriteableBrowsingExistingBlockNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(operation.NewNode, BlockIndex, Index); IWriteablePlaceholderNodeState NewChildState = (IWriteablePlaceholderNodeState)CreateNodeState(NewBrowsingIndex); BlockState.Insert(NewBrowsingIndex, Index, NewChildState); operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState); }
private protected virtual void UndoReplace(IWriteableOperation operation) { IWriteableReplaceOperation ReplaceOperation = (IWriteableReplaceOperation)operation; ReplaceOperation = ReplaceOperation.ToInverseReplace(); ExecuteReplace(ReplaceOperation); }
/// <summary> /// Split an identifier with replace and insert indexes. /// </summary> /// <param name="inner">The inner where the node is replaced.</param> /// <param name="replaceIndex">Index for the replace operation.</param> /// <param name="insertIndex">Index for the insert operation.</param> /// <param name="firstIndex">Index of the replacing node upon return.</param> /// <param name="secondIndex">Index of the inserted node upon return.</param> public virtual void SplitIdentifier(IWriteableListInner inner, IWriteableInsertionListNodeIndex replaceIndex, IWriteableInsertionListNodeIndex insertIndex, out IWriteableBrowsingListNodeIndex firstIndex, out IWriteableBrowsingListNodeIndex secondIndex) { Contract.RequireNotNull(inner, out IWriteableListInner Inner); Contract.RequireNotNull(replaceIndex, out IWriteableInsertionListNodeIndex ReplaceIndex); Contract.RequireNotNull(insertIndex, out IWriteableInsertionListNodeIndex InsertIndex); IWriteableNodeState Owner = Inner.Owner; IWriteableIndex ParentIndex = Owner.ParentIndex; Debug.Assert(Contains(ParentIndex)); Debug.Assert(IndexToState(ParentIndex) == Owner); WriteableInnerReadOnlyDictionary <string> InnerTable = Owner.InnerTable; Debug.Assert(InnerTable.ContainsKey(Inner.PropertyName)); Debug.Assert(InnerTable[Inner.PropertyName] == Inner); int Index = ReplaceIndex.Index; Debug.Assert(InsertIndex.Index == Index + 1); Node ReplacingNode = ReplaceIndex.Node; Node InsertedNode = InsertIndex.Node; Action <IWriteableOperation> HandlerRedoReplace = (IWriteableOperation operation) => RedoReplace(operation); Action <IWriteableOperation> HandlerUndoReplace = (IWriteableOperation operation) => UndoReplace(operation); IWriteableReplaceOperation ReplaceOperation = CreateReplaceOperation(Inner.Owner.Node, Inner.PropertyName, -1, Index, clearNode: false, ReplacingNode, HandlerRedoReplace, HandlerUndoReplace, isNested: true); Action <IWriteableOperation> HandlerRedoInsert = (IWriteableOperation operation) => RedoInsertNewNode(operation); Action <IWriteableOperation> HandlerUndoInsert = (IWriteableOperation operation) => UndoInsertNewNode(operation); WriteableInsertNodeOperation InsertOperation = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, -1, Index + 1, InsertedNode, HandlerRedoInsert, HandlerUndoInsert, isNested: true); ReplaceOperation.Redo(); InsertOperation.Redo(); Action <IWriteableOperation> HandlerRedoRefresh = (IWriteableOperation operation) => RedoRefresh(operation); Action <IWriteableOperation> HandlerUndoRefresh = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible. WriteableGenericRefreshOperation RefreshOperation = CreateGenericRefreshOperation(RootState, HandlerRedoRefresh, HandlerUndoRefresh, isNested: false); RefreshOperation.Redo(); WriteableOperationList OperationList = CreateOperationList(); OperationList.Add(ReplaceOperation); OperationList.Add(InsertOperation); WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly(); WriteableOperationGroup OperationGroup = CreateOperationGroup(OperationReadOnlyList, RefreshOperation); SetLastOperation(OperationGroup); CheckInvariant(); firstIndex = ReplaceOperation.NewBrowsingIndex as IWriteableBrowsingListNodeIndex; Debug.Assert(firstIndex != null); secondIndex = InsertOperation.BrowsingIndex as IWriteableBrowsingListNodeIndex; Debug.Assert(secondIndex != null); }
private protected virtual void ExecuteReplace(IWriteableReplaceOperation operation) { Node ParentNode = operation.ParentNode; string PropertyName = operation.PropertyName; IWriteableInner <IWriteableBrowsingChildIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableInner <IWriteableBrowsingChildIndex>; ReplaceState(operation, Inner); Debug.Assert(Contains(operation.NewBrowsingIndex)); NotifyStateReplaced(operation); }
private protected virtual void ReplaceState(IWriteableReplaceOperation operation, IWriteableInner <IWriteableBrowsingChildIndex> inner) { Contract.RequireNotNull(inner, out IWriteableInner <IWriteableBrowsingChildIndex> Inner); IWriteableNodeState Owner = Inner.Owner; IWriteableIndex ParentIndex = Owner.ParentIndex; Debug.Assert(Contains(ParentIndex)); Debug.Assert(IndexToState(ParentIndex) == Owner); WriteableInnerReadOnlyDictionary <string> InnerTable = Owner.InnerTable; Debug.Assert(InnerTable.ContainsKey(Inner.PropertyName)); Debug.Assert(InnerTable[Inner.PropertyName] == Inner); IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> AsOptionalInner = Inner as IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex>; if (AsOptionalInner != null) { IWriteableNodeState OldState = AsOptionalInner.ChildState; PruneStateChildren(OldState); if (AsOptionalInner.IsAssigned) { Stats.AssignedOptionalNodeCount--; } } Inner.Replace(operation); IWriteableBrowsingChildIndex OldBrowsingIndex = operation.OldBrowsingIndex; IWriteableBrowsingChildIndex NewBrowsingIndex = operation.NewBrowsingIndex; IWriteableNodeState ChildState = operation.NewChildState; if (AsOptionalInner != null) { if (AsOptionalInner.IsAssigned) { Stats.AssignedOptionalNodeCount++; } } else { Debug.Assert(Contains(OldBrowsingIndex)); IWriteableNodeState OldState = (IWriteableNodeState)StateTable[OldBrowsingIndex]; PruneStateChildren(OldState); } RemoveState(OldBrowsingIndex); AddState(NewBrowsingIndex, ChildState); BuildStateTable(Inner, null, NewBrowsingIndex, ChildState); }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { Debug.Assert(operation != null); if (operation.NewNode != null) { ReplaceOptional(operation); } else { ClearOptional(operation); } }
private protected virtual void ClearOptional(IWriteableReplaceOperation operation) { INode ParentNode = Owner.Node; WriteableBrowsingOptionalNodeIndex OldBrowsingIndex = (WriteableBrowsingOptionalNodeIndex)ChildState.ParentIndex; INode OldNode = ChildState.Optional.HasItem ? ChildState.Node : null; NodeTreeHelperOptional.ClearOptionalChildNode(ParentNode, PropertyName); IWriteableBrowsingOptionalNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(); IWriteableOptionalNodeState NewChildState = (IWriteableOptionalNodeState)CreateNodeState(NewBrowsingIndex); SetChildState(NewChildState); operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState); }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { Node ParentNode = Owner.Node; IWriteableBrowsingPlaceholderNodeIndex OldBrowsingIndex = (IWriteableBrowsingPlaceholderNodeIndex)ChildState.ParentIndex; IWriteablePlaceholderNodeState OldChildState = (IWriteablePlaceholderNodeState)ChildState; Node OldNode = OldChildState.Node; NodeTreeHelperChild.SetChildNode(ParentNode, PropertyName, operation.NewNode); IWriteableBrowsingPlaceholderNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(operation.NewNode); IWriteablePlaceholderNodeState NewChildState = (IWriteablePlaceholderNodeState)CreateNodeState(NewBrowsingIndex); SetChildState(NewChildState); operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState); }
/// <summary> /// Handler called every time a state is replaced in the controller. /// </summary> /// <param name="operation">Details of the operation performed.</param> private protected virtual void OnStateReplaced(IWriteableReplaceOperation operation) { IWriteableNodeState NewChildState = operation.NewChildState; Debug.Assert(NewChildState != null); Debug.Assert(StateViewTable.ContainsKey(NewChildState)); IWriteableBrowsingChildIndex OldBrowsingIndex = operation.OldBrowsingIndex; Debug.Assert(OldBrowsingIndex != null); Debug.Assert(NewChildState.ParentIndex != OldBrowsingIndex); IWriteableBrowsingChildIndex NewBrowsingIndex = operation.NewBrowsingIndex; Debug.Assert(NewBrowsingIndex != null); Debug.Assert(NewChildState.ParentIndex == NewBrowsingIndex); }
/// <summary> /// Handler called every time a state is inserted in the controller. /// </summary> /// <param name="operation">Details of the operation performed.</param> private protected override void OnStateReplaced(IWriteableReplaceOperation operation) { base.OnStateReplaced(operation); IFocusNodeState NewChildState = ((IFocusReplaceOperation)operation).NewChildState; Debug.Assert(NewChildState != null); Debug.Assert(StateViewTable.ContainsKey(NewChildState)); IFocusBrowsingChildIndex OldBrowsingIndex = ((IFocusReplaceOperation)operation).OldBrowsingIndex; Debug.Assert(OldBrowsingIndex != null); Debug.Assert(NewChildState.ParentIndex != OldBrowsingIndex); IFocusBrowsingChildIndex NewBrowsingIndex = ((IFocusReplaceOperation)operation).NewBrowsingIndex; Debug.Assert(NewBrowsingIndex != null); Debug.Assert(NewChildState.ParentIndex == NewBrowsingIndex); }
private protected virtual void ReplaceOptional(IWriteableReplaceOperation operation) { Node ParentNode = Owner.Node; IWriteableBrowsingOptionalNodeIndex OldBrowsingIndex = (IWriteableBrowsingOptionalNodeIndex)ChildState.ParentIndex; Node OldNode = ChildState.Node; if (operation.ClearNode) { NodeTreeHelperOptional.UnassignChildNode(ParentNode, PropertyName); } else { NodeTreeHelperOptional.SetOptionalChildNode(ParentNode, PropertyName, operation.NewNode); } IWriteableBrowsingOptionalNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(); IWriteableOptionalNodeState NewChildState = (IWriteableOptionalNodeState)CreateNodeState(NewBrowsingIndex); SetChildState(NewChildState); operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState); }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public abstract void Replace(IWriteableReplaceOperation operation);
private protected virtual void NotifyStateReplaced(IWriteableReplaceOperation operation) { StateReplacedHandler?.Invoke(operation); }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { throw new NotSupportedException(); }
private protected virtual void RedoReplace(IWriteableOperation operation) { IWriteableReplaceOperation ReplaceOperation = (IWriteableReplaceOperation)operation; ExecuteReplace(ReplaceOperation); }
/// <summary> /// Replaces a node. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Replace(IWriteableReplaceOperation operation) { Debug.Assert(operation.NewNode != null || operation.ClearNode); ReplaceOptional(operation); }