private protected virtual IReadOnlyInner BuildInner(IReadOnlyNodeState parentState, IReadOnlyIndexCollection nodeIndexCollection)
        {
            IReadOnlyInner Result = null;

            switch (nodeIndexCollection)
            {
            case IReadOnlyIndexCollection <IReadOnlyBrowsingPlaceholderNodeIndex> AsPlaceholderNodeIndexCollection:
                Result = (IReadOnlyPlaceholderInner)CreatePlaceholderInner(parentState, AsPlaceholderNodeIndexCollection);
                break;

            case IReadOnlyIndexCollection <IReadOnlyBrowsingOptionalNodeIndex> AsOptionalNodeIndexCollection:
                Result = (IReadOnlyOptionalInner)CreateOptionalInner(parentState, AsOptionalNodeIndexCollection);
                break;

            case IReadOnlyIndexCollection <IReadOnlyBrowsingListNodeIndex> AsListNodeIndexCollection:
                Stats.ListCount++;
                Result = (IReadOnlyListInner)CreateListInner(parentState, AsListNodeIndexCollection);
                break;

            case IReadOnlyIndexCollection <IReadOnlyBrowsingBlockNodeIndex> AsBlockNodeIndexCollection:
                Stats.BlockListCount++;
                IReadOnlyBlockListInner Inner = (IReadOnlyBlockListInner)CreateBlockListInner(parentState, AsBlockNodeIndexCollection);
                NotifyBlockListInnerCreated(Inner as IReadOnlyBlockListInner);
                Result = Inner;
                break;
            }

            Debug.Assert(Result != null);
            return(Result);
        }
        private protected virtual ReadOnlyInnerReadOnlyDictionary <string> BuildInnerTable(ReadOnlyBrowseContext browseContext)
        {
            IReadOnlyNodeState State = browseContext.State;

            Debug.Assert(State.InnerTable == null);

            ReadOnlyIndexCollectionReadOnlyList IndexCollectionList = browseContext.IndexCollectionList;
            ReadOnlyInnerDictionary <string>    InnerTable          = CreateInnerTable();

            foreach (IReadOnlyIndexCollection NodeIndexCollection in IndexCollectionList)
            {
                string PropertyName = NodeIndexCollection.PropertyName;
                Debug.Assert(!InnerTable.ContainsKey(PropertyName));

                IReadOnlyInner Inner = BuildInner(State, NodeIndexCollection);
                InnerTable.Add(PropertyName, Inner);
            }

            if (InnerTable.Count > 0)
            {
                DebugObjects.AddReference(InnerTable);
            }

            return(InnerTable.ToReadOnly());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a newly created state.
        /// </summary>
        /// <param name="parentInner">Inner containing this state.</param>
        /// <param name="innerTable">Table for all inners in this state.</param>
        /// <param name="valuePropertyTable">Table of children that are not nodes.</param>
        public virtual void Init(IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner, IReadOnlyInnerReadOnlyDictionary <string> innerTable, IReadOnlyDictionary <string, ValuePropertyType> valuePropertyTable)
        {
            Debug.Assert(innerTable != null);
            Debug.Assert(valuePropertyTable != null);
            Debug.Assert(!IsInitialized);
            Debug.Assert(ParentInner == null);
            Debug.Assert(InnerTable == null);
            Debug.Assert(ValuePropertyTypeTable == null);

            InitParentInner(parentInner);
            if (parentInner != null) // The root node doesn't have a parent inner.
            {
                InitParentState(ParentInner.Owner);
            }
            InitInnerTable(innerTable);

            Dictionary <string, ValuePropertyType> Table = new Dictionary <string, ValuePropertyType>();

            foreach (KeyValuePair <string, ValuePropertyType> Entry in valuePropertyTable)
            {
                Table.Add(Entry.Key, Entry.Value);
            }

            ValuePropertyTypeTable = Table;
            IsInitialized          = true;

            CheckInvariant();
        }
        bool IDictionary <TKey, IReadOnlyInner> .TryGetValue(TKey key, out IReadOnlyInner value)
        {
            bool Result = TryGetValue(key, out IFrameInner Value);

            value = Value;
            return(Result);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Browse the optional node in the node tree.
        /// </summary>
        /// <param name="browseContext">The context used to browse the node tree.</param>
        /// <param name="parentInner">The inner containing this state as a child.</param>
        public override void BrowseChildren(ReadOnlyBrowseContext browseContext, IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner)
        {
            NodeTreeHelperOptional.GetChildNode(Optional, out bool IsAssigned, out Node ChildNode);

            if (ChildNode != null)
            {
                BrowseChildrenOfNode(browseContext, ChildNode);
            }
        }
        /// <summary>
        /// Returns a clone of the node of this state.
        /// </summary>
        /// <returns>The cloned node.</returns>
        public override INode CloneNode()
        {
            INode NewNode = null;

            NodeTreeHelperOptional.GetChildNode(Optional, out bool IsAssigned, out INode ChildNode);
            if (ChildNode != null)
            {
                // Create a clone, initially empty and full of null references.
                NewNode = NodeHelper.CreateEmptyNode(ChildNode.GetType());

                // Clone and assign reference to all nodes, optional or not, list and block lists.
                foreach (KeyValuePair <string, IReadOnlyInner> Entry in InnerTable)
                {
                    string         PropertyName = Entry.Key;
                    IReadOnlyInner Inner        = Entry.Value;
                    ((IReadOnlyInner <IReadOnlyBrowsingChildIndex>)Inner).CloneChildren(NewNode);
                }

                // Copy other properties.
                foreach (KeyValuePair <string, ValuePropertyType> Entry in ValuePropertyTypeTable)
                {
                    string            PropertyName = Entry.Key;
                    ValuePropertyType Type         = Entry.Value;
                    bool IsHandled = false;

                    switch (Type)
                    {
                    case ValuePropertyType.Boolean:
                        NodeTreeHelper.CopyBooleanProperty(Node, NewNode, Entry.Key);
                        IsHandled = true;
                        break;

                    case ValuePropertyType.Enum:
                        NodeTreeHelper.CopyEnumProperty(Node, NewNode, Entry.Key);
                        IsHandled = true;
                        break;

                    case ValuePropertyType.String:
                        NodeTreeHelper.CopyStringProperty(Node, NewNode, Entry.Key);
                        IsHandled = true;
                        break;

                    case ValuePropertyType.Guid:
                        NodeTreeHelper.CopyGuidProperty(Node, NewNode, Entry.Key);
                        IsHandled = true;
                        break;
                    }

                    Debug.Assert(IsHandled);
                }

                // Also copy comments.
                NodeTreeHelper.CopyDocumentation(Node, NewNode, cloneCommentGuid: true);
            }

            return(NewNode);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Detach a view to the state.
        /// </summary>
        /// <param name="view">The attaching view.</param>
        /// <param name="callbackSet">The set of callbacks to no longer call when enumerating existing states.</param>
        public virtual void Detach(IReadOnlyControllerView view, IReadOnlyAttachCallbackSet callbackSet)
        {
            foreach (KeyValuePair <string, IReadOnlyInner> Entry in InnerTable)
            {
                IReadOnlyInner Inner = Entry.Value;
                ((IReadOnlyInner <IReadOnlyBrowsingChildIndex>)Inner).Detach(view, callbackSet);
            }

            callbackSet.OnNodeStateDetached(this);
        }
Exemplo n.º 8
0
        private protected override void CheckInvariant()
        {
            InvariantAssert(IsInitialized);

            foreach (KeyValuePair <string, IReadOnlyInner> Entry in InnerTable)
            {
                IReadOnlyInner Inner = Entry.Value;

                InvariantAssert((Inner is IReadOnlyBlockListInner) || (Inner is IReadOnlyListInner) || (Inner is IReadOnlyOptionalInner) || (Inner is IReadOnlyPlaceholderInner));
                InvariantAssert(Inner.Owner == this);
            }
        }
        private protected virtual ReadOnlyNodeStateDictionary BuildChildrenStateTable(ReadOnlyBrowseContext browseContext)
        {
            IReadOnlyNodeState State = browseContext.State;
            ReadOnlyInnerReadOnlyDictionary <string> InnerTable          = State.InnerTable;
            ReadOnlyIndexCollectionReadOnlyList      IndexCollectionList = browseContext.IndexCollectionList;

            ReadOnlyNodeStateDictionary ChildStateTable = CreateChildStateTable();

            foreach (IReadOnlyIndexCollection <IReadOnlyBrowsingChildIndex> NodeIndexCollection in IndexCollectionList)
            {
                // List of indexes for this property (one for placeholder and optional node, several for lists and block lists)
                IReadOnlyList <IReadOnlyBrowsingChildIndex> NodeIndexList = NodeIndexCollection.NodeIndexList;
                string PropertyName = NodeIndexCollection.PropertyName;

                Debug.Assert(InnerTable.ContainsKey(PropertyName));
                IReadOnlyInner <IReadOnlyBrowsingChildIndex> Inner = (IReadOnlyInner <IReadOnlyBrowsingChildIndex>)InnerTable[PropertyName];

                for (int i = 0; i < NodeIndexList.Count; i++)
                {
                    IReadOnlyBrowsingChildIndex ChildIndex = NodeIndexList[i];

                    // If the inner is that of a block list, and the index is for the first node in the block, add block-specific states
                    if (Inner is IReadOnlyBlockListInner <IReadOnlyBrowsingBlockNodeIndex> AsBlockListInner && ChildIndex is IReadOnlyBrowsingNewBlockNodeIndex AsNewBlockIndex)
                    {
                        IReadOnlyBlockState BlockState = AsBlockListInner.InitNewBlock(AsNewBlockIndex);
                        ((IReadOnlyBlockState <IReadOnlyInner <IReadOnlyBrowsingChildIndex> >)BlockState).InitBlockState();
                        Stats.BlockCount++;

                        IReadOnlyBrowsingPatternIndex PatternIndex = BlockState.PatternIndex;
                        IReadOnlyPatternState         PatternState = BlockState.PatternState;
                        AddState(PatternIndex, PatternState);
                        Stats.PlaceholderNodeCount++;

                        IReadOnlyBrowsingSourceIndex SourceIndex = BlockState.SourceIndex;
                        IReadOnlySourceState         SourceState = BlockState.SourceState;
                        AddState(SourceIndex, SourceState);
                        Stats.PlaceholderNodeCount++;

                        ChildIndex = AsNewBlockIndex.ToExistingBlockIndex();
                    }

                    IReadOnlyNodeState ChildState = BuildChildState(Inner, ChildIndex);
                    ChildStateTable.Add(NodeIndexList[i], ChildState);
                }
            }

            return(ChildStateTable);
        }
        private protected virtual IReadOnlyInner <IReadOnlyBrowsingChildIndex> GetInner(Node parentNode, string propertyName)
        {
            IReadOnlyInner <IReadOnlyBrowsingChildIndex> Result = null;

            foreach (KeyValuePair <IReadOnlyIndex, IReadOnlyNodeState> Entry in StateTable)
            {
                IReadOnlyNodeState State = Entry.Value;

                if (State.Node == parentNode)
                {
                    Result = State.PropertyToInner(propertyName) as IReadOnlyInner <IReadOnlyBrowsingChildIndex>;
                    break;
                }
            }

            Debug.Assert(Result != null);
            return(Result);
        }
Exemplo n.º 11
0
        private void AddChildInner(IReadOnlyNodeStateList stateList, IReadOnlyInner inner)
        {
            bool IsHandled = false;

            switch (inner)
            {
            case IReadOnlyPlaceholderInner AsPlaceholderInner:
                AddChildStates(stateList, AsPlaceholderInner.ChildState);
                IsHandled = true;
                break;

            case IReadOnlyOptionalInner AsOptionalInner:
                if (AsOptionalInner.IsAssigned)
                {
                    AddChildStates(stateList, AsOptionalInner.ChildState);
                }
                IsHandled = true;
                break;

            case IReadOnlyListInner AsListInner:
                foreach (IReadOnlyNodeState ChildState in AsListInner.StateList)
                {
                    AddChildStates(stateList, ChildState);
                }
                IsHandled = true;
                break;

            case IReadOnlyBlockListInner AsBlockListInner:
                foreach (IReadOnlyBlockState Block in AsBlockListInner.BlockStateList)
                {
                    stateList.Add(Block.PatternState);
                    stateList.Add(Block.SourceState);

                    foreach (IReadOnlyNodeState ChildState in Block.StateList)
                    {
                        AddChildStates(stateList, ChildState);
                    }
                }
                IsHandled = true;
                break;
            }

            Debug.Assert(IsHandled);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Gets the inner corresponding to a property in a node.
        /// </summary>
        /// <param name="propertyName">Property name.</param>
        public virtual IReadOnlyInner <IReadOnlyBrowsingChildIndex> PropertyToInner(string propertyName)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName));

            IReadOnlyInner <IReadOnlyBrowsingChildIndex> Result = null;

            switch (propertyName)
            {
            case nameof(IBlock.ReplicationPattern):
                Result = PatternInner;
                break;

            case nameof(IBlock.SourceIdentifier):
                Result = SourceInner;
                break;
            }

            Debug.Assert(Result != null);
            return(Result);
        }
        private protected virtual void BuildChildrenStates(ReadOnlyBrowseContext browseContext, ReadOnlyNodeStateDictionary childrenStateTable)
        {
            IReadOnlyNodeState State = browseContext.State;
            ReadOnlyInnerReadOnlyDictionary <string> InnerTable          = State.InnerTable;
            ReadOnlyIndexCollectionReadOnlyList      IndexCollectionList = browseContext.IndexCollectionList;

            // Build states for children in the order they have been reported when browsing the parent state
            foreach (IReadOnlyIndexCollection <IReadOnlyBrowsingChildIndex> NodeIndexCollection in IndexCollectionList)
            {
                IReadOnlyList <IReadOnlyBrowsingChildIndex> NodeIndexList = NodeIndexCollection.NodeIndexList;
                string PropertyName = NodeIndexCollection.PropertyName;
                IReadOnlyInner <IReadOnlyBrowsingChildIndex> Inner = (IReadOnlyInner <IReadOnlyBrowsingChildIndex>)InnerTable[PropertyName];

                for (int i = 0; i < NodeIndexList.Count; i++)
                {
                    IReadOnlyBrowsingChildIndex ChildNodeIndex = NodeIndexList[i];
                    IReadOnlyNodeState          ChildState     = childrenStateTable[ChildNodeIndex];

                    BuildStateTable(Inner, browseContext, ChildState.ParentIndex, ChildState);
                }
            }
        }
        private protected virtual IReadOnlyNodeState BuildChildState(IReadOnlyInner <IReadOnlyBrowsingChildIndex> inner, IReadOnlyBrowsingChildIndex nodeIndex)
        {
            IReadOnlyNodeState ChildState = inner.InitChildState(nodeIndex);

            AddState(nodeIndex, ChildState);

            // For debugging: count nodes according to their type
            if (inner is IReadOnlyOptionalInner <IReadOnlyBrowsingOptionalNodeIndex> AsOptionalInner)
            {
                Stats.OptionalNodeCount++;
                if (AsOptionalInner.IsAssigned)
                {
                    Stats.AssignedOptionalNodeCount++;
                }
            }
            else
            {
                Stats.PlaceholderNodeCount++;
            }

            return(ChildState);
        }
        private protected virtual void BuildStateTable(IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner, ReadOnlyBrowseContext parentBrowseContext, IReadOnlyIndex nodeIndex, IReadOnlyNodeState state)
        {
            Debug.Assert((parentBrowseContext == null) || (parentBrowseContext != null && parentInner != null));
            Debug.Assert(Contains(nodeIndex));
            Debug.Assert(IndexToState(nodeIndex) == state);

            // Browse the uninitialized state for children
            ReadOnlyBrowseContext BrowseContext = CreateBrowseContext(parentBrowseContext, state);

            BrowseStateChildren(BrowseContext, parentInner);

            // Build inners for each child
            ReadOnlyInnerReadOnlyDictionary <string> InnerTable = BuildInnerTable(BrowseContext);

            // Initialize the state
            InitState(BrowseContext, parentInner, nodeIndex, InnerTable);

            // Build uninitialized states for each child
            ReadOnlyNodeStateDictionary ChildrenStateTable = BuildChildrenStateTable(BrowseContext);

            // Continue to build the table for each of them
            BuildChildrenStates(BrowseContext, ChildrenStateTable);
        }
Exemplo n.º 16
0
 void IDictionary <TKey, IReadOnlyInner> .Add(TKey key, IReadOnlyInner value)
 {
     Add(key, (IFrameInner)value);
 }
Exemplo n.º 17
0
 /// <summary>
 /// Find children in the node tree.
 /// </summary>
 /// <param name="browseContext">The context used to browse the node tree.</param>
 /// <param name="parentInner">The inner containing this state as a child.</param>
 public virtual void BrowseChildren(IReadOnlyBrowseContext browseContext, IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner)
 {
     BrowseChildrenOfNode(browseContext, Node);
 }
Exemplo n.º 18
0
        private protected virtual void InitParentInner(IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner)
        {
            Debug.Assert(ParentInner == null);

            ParentInner = (IReadOnlyInner)parentInner;
        }
Exemplo n.º 19
0
 void IDictionary <TKey, IReadOnlyInner> .Add(TKey key, IReadOnlyInner value)
 {
     Add(key, (IWriteableInner)value);
 }
        private protected virtual void InitState(ReadOnlyBrowseContext browseContext, IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner, IReadOnlyIndex nodeIndex, ReadOnlyInnerReadOnlyDictionary <string> innerTable)
        {
            Debug.Assert(Contains(nodeIndex));
            Debug.Assert(parentInner != null || nodeIndex == RootIndex);

            IReadOnlyNodeState State = browseContext.State;

            Debug.Assert(IndexToState(nodeIndex) == State);
            Debug.Assert(State.ParentInner == null);
            Debug.Assert(State.ParentIndex == nodeIndex);
            Debug.Assert(State.ParentState == null);
            Debug.Assert(State.InnerTable == null);
            Debug.Assert(State.IsEmptyValuePropertyTypeTable || State.ValuePropertyTypeTable.Count == 0);

            ((IReadOnlyNodeState <IReadOnlyInner <IReadOnlyBrowsingChildIndex> >)State).Init(parentInner, innerTable, browseContext.ValuePropertyTypeTable);

            NotifyNodeStateInitialized(State);
        }
        private protected virtual void BrowseStateChildren(ReadOnlyBrowseContext browseContext, IReadOnlyInner <IReadOnlyBrowsingChildIndex> parentInner)
        {
            Debug.Assert(browseContext.IndexCollectionList.Count == 0);

            IReadOnlyNodeState State = browseContext.State;

            ((IReadOnlyNodeState <IReadOnlyInner <IReadOnlyBrowsingChildIndex> >)State).BrowseChildren(browseContext, parentInner);

            CheckContextConsistency(browseContext);
        }