Exemplo n.º 1
0
        /// <summary>
        /// Try to get the mapping from MetaTree. If the data are not in the tree, try to create and add it.
        /// </summary>
        internal static PlcObject GetMapping(string name, ITree tree, Type t, bool allowAddingWithoutMappingAttribute = false)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                return(null);
            }
            var nodePathStack = new Stack <string>();

            nodePathStack.Push(RootNodeName);
            nodePathStack.Push(InstancesNodeName);
            foreach (var part in name.Split('.'))
            {
                nodePathStack.Push(part);
            }

            var path   = PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray());
            var offset = 0;

            if (!tree.TryGet(path, ref offset, out var obj, true))
            {
                if (t == null)
                {
                    ExceptionThrowHelper.ThrowArgumentNullException(nameof(t));
                }

                var mapping = t.GetTypeInfo().GetCustomAttributes <MappingAttribute>().FirstOrDefault(m => m.Name == name);
                if (mapping != null)
                {
                    nodePathStack.Pop();
                    var plcObj = new PlcObjectRef(name, GetMetaData(tree, t))
                    {
                        Offset   = { Bytes = mapping.Offset },
                        Selector = mapping.Selector
                    };
                    PlcObject.AddPlcObjectToTree(plcObj, tree, PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray()));
                    obj = plcObj;
                }
                else if (allowAddingWithoutMappingAttribute)
                {
                    nodePathStack.Pop();
                    var plcObj = new PlcObjectRef(name, GetMetaData(tree, t));
                    PlcObject.AddPlcObjectToTree(plcObj, tree, PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray()));
                    obj = plcObj;
                }
                else
                {
                    ExceptionThrowHelper.ThrowInvalidMappingNameException(name);
                }
            }
            return(obj as PlcObject);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Try to get Meta data from MetaTree. If the data are not in the tree, try to create and add it.
        /// All the calculation of the offsets will be made in this method. the tree has two parts, one for MetaData and one for The Mappings.
        /// The mappings have only a Reference of the Meta data, so you shouldn't change the Offsets while using.
        /// </summary>
        private static PlcObject GetMetaData(ITree tree, Type t)
        {
            var nodePathStack = new Stack <string>();
            var name          = NormalizeTypeName(t.FullName);

            nodePathStack.Push(RootNodeName);
            nodePathStack.Push(MetaDataNodeName);
            nodePathStack.Push(name);
            var path   = PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray());
            var offset = 0;

            if (!tree.TryGet(path, ref offset, out var obj))
            {
                var byteOffset = 0;
                var bitOffset  = 0;
                nodePathStack.Pop();
                var parent = new PlcStruct(name, t);
                PlcObject.AddPlcObjectToTree(parent, tree, PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray()));
                nodePathStack.Push(parent.Name);
                PlcObject pred = null;
                DebugOutPut("{0}{{", name);

                foreach (var pi in t.GetTypeInfo().DeclaredProperties)
                {
                    var plcObject = PlcObjectFactory.CreatePlcObject(pi);

                    if (plcObject is PlcArray plcObjectArray && (plcObjectArray.LeafElementType ?? plcObjectArray.ArrayType) is PlcStruct)
                    {
                        plcObjectArray.ArrayType = GetMetaData(tree, plcObjectArray.ElemenType);
                    }
                    else if (plcObject is PlcStruct)
                    {
                        plcObject = new PlcObjectRef(plcObject.Name, GetMetaData(tree, pi.PropertyType));
                    }


                    var hasCustomOffset = PlcObjectFactory.GetOffsetFromAttribute(pi, ref byteOffset, ref bitOffset);
                    AddPlcObject(tree, pred, plcObject, nodePathStack, ref byteOffset, ref bitOffset, hasCustomOffset);
                    pred = plcObject;
                }
Exemplo n.º 3
0
        /// <summary>
        /// Get all leafs from the meta tree, normally this should b only value types.
        /// </summary>
        /// <param name="obj">TreeNode</param>
        /// <param name="path">Path to node</param>
        /// <returns>List of leafs</returns>
        public static IEnumerable <string> GetLeafs(ITreeNode obj, ICollection <string> path)
        {
            var list = new List <string>();

            if (obj != null)
            {
                var idx = obj.Name.IndexOf("[", StringComparison.Ordinal);

                if (idx >= 0)
                {
                    var p = path.Last();
                    path = new List <string>(path.Take(path.Count - 1))
                    {
                        p + obj.Name.Substring(idx)
                    };
                }
                else
                {
                    path.Add(obj.Name);
                }
                if (obj.Childs.Any())
                {
                    if (obj is PlcArray)
                    {
                        foreach (var child in obj.Childs)
                        {
                            if (child.Childs.Any())
                            {
                                var nunmberOfChilds = child.Childs.Count();
                                var internalPath    = new List <string>(path.Take(path.Count - 1))
                                {
                                    obj.Name + child.Name
                                };
                                foreach (var c in child.Childs)
                                {
                                    list.AddRange(GetLeafs(c, internalPath.ToList()));
                                }
                            }
                            else
                            {
                                var internalPath = new List <string>(path.Take(path.Count - 1))
                                {
                                    child.Name
                                };
                                list.Add(PlcMetaDataTreePath.CreateAbsolutePath(internalPath.Skip(1).ToArray()).Path.Substring(1));
                            }
                        }
                    }
                    else
                    {
                        foreach (var child in obj.Childs)
                        {
                            list.AddRange(GetLeafs(child, path.ToList()));
                        }
                    }
                }
                else
                {
                    list.Add(PlcMetaDataTreePath.CreateAbsolutePath(path.Skip(1).ToArray()).Path.Substring(1));
                }
            }
            return(list);
        }