/// <summary>
        /// Does any initialization required before the address space can be used.
        /// </summary>
        /// <remarks>
        /// The externalReferences is an out parameter that allows the node manager to link to nodes
        /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
        /// should have a reference to the root folder node(s) exposed by this node manager.
        /// </remarks>
        public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            lock (Lock) {
                // find the top level segments and link them to the ObjectsFolder.
                var segments = _system.FindSegments(null);

                for (var ii = 0; ii < segments.Count; ii++)
                {
                    // Top level areas need a reference from the Server object.
                    // These references are added to a list that is returned to the caller.
                    // The caller will update the Objects folder node.

                    if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out var references))
                    {
                        externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>();
                    }

                    // construct the NodeId of a segment.
                    var segmentId = ModelUtils.ConstructIdForSegment(segments[ii].Id, NamespaceIndex);

                    // add an organizes reference from the ObjectsFolder to the area.
                    references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, segmentId));
                }

                // start the simulation.
                _system.StartSimulation();
            }
        }
Example #2
0
        /// <summary>
        /// Populates the browser with references that meet the criteria.
        /// </summary>
        /// <param name="context">The context for the system being accessed.</param>
        /// <param name="browser">The browser to populate.</param>
        protected override void PopulateBrowser(ISystemContext context, NodeBrowser browser)
        {
            base.PopulateBrowser(context, browser);

            // check if the parent segments need to be returned.
            if (browser.IsRequired(ReferenceTypeIds.Organizes, true))
            {
                if (!(context.SystemHandle is UnderlyingSystem system))
                {
                    return;
                }

                // add reference for parent segment.
                var segment = system.FindParentForSegment(SegmentPath);

                if (segment != null)
                {
                    browser.Add(ReferenceTypeIds.Organizes, true, ModelUtils.ConstructIdForSegment(segment.Id, NodeId.NamespaceIndex));
                }
            }
        }
Example #3
0
        /// <summary>
        /// Populates the browser with references that meet the criteria.
        /// </summary>
        /// <param name="context">The context for the system being accessed.</param>
        /// <param name="browser">The browser to populate.</param>
        protected override void PopulateBrowser(ISystemContext context, NodeBrowser browser)
        {
            base.PopulateBrowser(context, browser);

            // check if the parent segments need to be returned.
            if (browser.IsRequired(ReferenceTypeIds.Organizes, true))
            {
                if (!(context.SystemHandle is UnderlyingSystem system))
                {
                    return;
                }

                // add reference for each segment.
                var segments = system.FindSegmentsForBlock(_blockId);

                for (var ii = 0; ii < segments.Count; ii++)
                {
                    browser.Add(ReferenceTypeIds.Organizes, true, ModelUtils.ConstructIdForSegment(segments[ii].Id, NodeId.NamespaceIndex));
                }
            }
        }
Example #4
0
        /// <summary>
        /// Returns the next child.
        /// </summary>
        private IReference NextChild()
        {
            var system = (UnderlyingSystem)SystemContext.SystemHandle;

            NodeId targetId = null;

            // check if a specific browse name is requested.
            if (!QualifiedName.IsNull(BrowseName))
            {
                // check if match found previously.
                if (_position == int.MaxValue)
                {
                    return(null);
                }

                // browse name must be qualified by the correct namespace.
                if (_source.BrowseName.NamespaceIndex != BrowseName.NamespaceIndex)
                {
                    return(null);
                }

                // look for matching segment.
                if (_stage == Stage.Segments && _segments != null)
                {
                    for (var ii = 0; ii < _segments.Count; ii++)
                    {
                        if (BrowseName.Name == _segments[ii].Name)
                        {
                            targetId = ModelUtils.ConstructIdForSegment(_segments[ii].Id, _source.NodeId.NamespaceIndex);
                            break;
                        }
                    }
                }

                // look for matching block.
                if (_stage == Stage.Blocks && _blocks != null)
                {
                    for (var ii = 0; ii < _blocks.Count; ii++)
                    {
                        var block = system.FindBlock(_blocks[ii]);

                        if (block != null && BrowseName.Name == block.Name)
                        {
                            targetId = ModelUtils.ConstructIdForBlock(_blocks[ii], _source.NodeId.NamespaceIndex);
                            break;
                        }
                    }
                }

                _position = int.MaxValue;
            }

            // return the child at the next position.
            else
            {
                // look for next segment.
                if (_stage == Stage.Segments && _segments != null)
                {
                    if (_position >= _segments.Count)
                    {
                        return(null);
                    }

                    targetId = ModelUtils.ConstructIdForSegment(_segments[_position++].Id, _source.NodeId.NamespaceIndex);
                }

                // look for next block.
                else if (_stage == Stage.Blocks && _blocks != null)
                {
                    if (_position >= _blocks.Count)
                    {
                        return(null);
                    }

                    targetId = ModelUtils.ConstructIdForBlock(_blocks[_position++], _source.NodeId.NamespaceIndex);
                }
            }

            // create reference.
            if (targetId != null)
            {
                return(new NodeStateReference(ReferenceTypeIds.Organizes, false, targetId));
            }

            return(null);
        }
 /// <summary>
 /// Creates the NodeId for the specified node.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="node">The node.</param>
 /// <returns>The new NodeId.</returns>
 /// <remarks>
 /// This method is called by the NodeState.Create() method which initializes a Node from
 /// the type model. During initialization a number of child nodes are created and need to
 /// have NodeIds assigned to them. This implementation constructs NodeIds by constructing
 /// strings. Other implementations could assign unique integers or Guids and save the new
 /// Node in a dictionary for later lookup.
 /// </remarks>
 public override NodeId New(ISystemContext context, NodeState node)
 {
     return(ModelUtils.ConstructIdForComponent(node, NamespaceIndex));
 }
        /// <summary>
        /// Verifies that the specified node exists.
        /// </summary>
        protected override NodeState ValidateNode(
            ServerSystemContext context,
            NodeHandle handle,
            IDictionary <NodeId, NodeState> cache)
        {
            // not valid if no root.
            if (handle == null)
            {
                return(null);
            }

            // check if previously validated.
            if (handle.Validated)
            {
                return(handle.Node);
            }

            NodeState target = null;

            // check if already in the cache.
            if (cache != null)
            {
                if (cache.TryGetValue(handle.NodeId, out target))
                {
                    // nulls mean a NodeId which was previously found to be invalid has been referenced again.
                    if (target == null)
                    {
                        return(null);
                    }

                    handle.Node      = target;
                    handle.Validated = true;
                    return(handle.Node);
                }

                target = null;
            }

            try {
                // check if the node id has been parsed.
                if (!(handle.ParsedNodeId is ParsedNodeId parsedNodeId))
                {
                    return(null);
                }

                NodeState root = null;

                // validate a segment.
                if (parsedNodeId.RootType == ModelUtils.Segment)
                {
                    var segment = _system.FindSegment(parsedNodeId.RootId);

                    // segment does not exist.
                    if (segment == null)
                    {
                        return(null);
                    }

                    var rootId = ModelUtils.ConstructIdForSegment(segment.Id, NamespaceIndex);

                    // create a temporary object to use for the operation.
                    root = new SegmentState(context, rootId, segment);
                }

                // validate segment.
                else if (parsedNodeId.RootType == ModelUtils.Block)
                {
                    // validate the block.
                    var block = _system.FindBlock(parsedNodeId.RootId);

                    // block does not exist.
                    if (block == null)
                    {
                        return(null);
                    }

                    var rootId = ModelUtils.ConstructIdForBlock(block.Id, NamespaceIndex);

                    // check for check for blocks that are being currently monitored.

                    if (_blocks.TryGetValue(rootId, out var node))
                    {
                        root = node;
                    }

                    // create a temporary object to use for the operation.
                    else
                    {
                        root = new BlockState(this, rootId, block);
                    }
                }

                // unknown root type.
                else
                {
                    return(null);
                }

                // all done if no components to validate.
                if (string.IsNullOrEmpty(parsedNodeId.ComponentPath))
                {
                    handle.Validated = true;
                    handle.Node      = target = root;
                    return(handle.Node);
                }

                // validate component.
                NodeState component = root.FindChildBySymbolicName(context, parsedNodeId.ComponentPath);

                // component does not exist.
                if (component == null)
                {
                    return(null);
                }

                // found a valid component.
                handle.Validated = true;
                handle.Node      = target = component;
                return(handle.Node);
            }
            finally {
                // store the node in the cache to optimize subsequent lookups.
                if (cache != null)
                {
                    cache.Add(handle.NodeId, target);
                }
            }
        }