/// <summary> /// Unassign the optional node. /// </summary> /// <param name="nodeIndex">Index of the optional node.</param> /// <param name="isChanged">True upon return if the node was changed. False if the node was already not assigned.</param> public virtual void Unassign(IWriteableBrowsingOptionalNodeIndex nodeIndex, out bool isChanged) { Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingOptionalNodeIndex NodeIndex); Debug.Assert(StateTable.ContainsKey(NodeIndex)); IWriteableOptionalNodeState State = StateTable[NodeIndex] as IWriteableOptionalNodeState; Debug.Assert(State != null); IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> Inner = State.ParentInner as IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex>; Debug.Assert(Inner != null); if (Inner.IsAssigned) { Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoUnassign(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoUnassign(operation); WriteableAssignmentOperation Operation = CreateAssignmentOperation(Inner.Owner.Node, Inner.PropertyName, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); isChanged = true; } else { isChanged = false; } }
private protected virtual void PruneOptionalInner(IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> inner) { PruneState(inner.ChildState); Stats.OptionalNodeCount--; if (inner.IsAssigned) { Stats.AssignedOptionalNodeCount--; } }
private protected virtual void ExecuteAssign(WriteableAssignmentOperation operation) { Node ParentNode = operation.ParentNode; string PropertyName = operation.PropertyName; IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex>; Inner.Assign(operation); Stats.AssignedOptionalNodeCount++; NotifyStateAssigned(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> /// Reduces the optional node. /// </summary> private protected virtual void ReduceOptional(IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> optionalInner, WriteableOperationList operationList, bool isNested) { if (optionalInner.IsAssigned && NodeHelper.IsOptionalAssignedToDefault(optionalInner.ChildState.Optional)) { IWriteableBrowsingOptionalNodeIndex ParentIndex = optionalInner.ChildState.ParentIndex; Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoUnassign(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoUnassign(operation); WriteableAssignmentOperation Operation = CreateAssignmentOperation(optionalInner.Owner.Node, optionalInner.PropertyName, HandlerRedo, HandlerUndo, isNested); Operation.Redo(); operationList.Add(Operation); } }
/// <summary> /// Expands the optional node. /// * If assigned, does nothing. /// * If it has an item, assign it. /// * Otherwise, assign the item to a default node. /// </summary> private protected virtual void ExpandOptional(IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> optionalInner, WriteableOperationList operationList) { if (optionalInner.IsAssigned) { return; } IWriteableBrowsingOptionalNodeIndex ParentIndex = optionalInner.ChildState.ParentIndex; Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoAssign(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoAssign(operation); WriteableAssignmentOperation Operation = CreateAssignmentOperation(optionalInner.Owner.Node, optionalInner.PropertyName, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); operationList.Add(Operation); }