Example #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);
        }
Example #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;
                }