| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 | using System;using System.Collections;using System.Linq;using System.Runtime.InteropServices;using System.Threading;namespace WCS.Core{    public delegate void ValueChangedHandler<T>(PlcItem<T> sender, T value);    public delegate void ValueChangedHandler(PlcItem sender, object value);    public abstract class PlcItem    {        protected DataBlock Db;        public int Start;//按位计算 如,第2个字节,Start=8        public byte ArrayLength, StringLength;        public string Id;        public string Name;        public string IP;        public ushort DB;        public Type DataType { get; private set; }        /// <summary>        /// 数据类型所占的字节数        /// </summary>        public byte DataSize { get; private set; }        public int DataSizeOfBits { get; private set; }        public PlcItem(string id, string name, DataBlock db, Type type, int start, byte arrLen = 1, byte strLength = 0)        {            this.Id = id;            this.Name = name;            this.Db = db;            this.DataType = type;            //this.Db.DBChanged += Db_DBChanged;            this.Start = start;            this.ArrayLength = arrLen;            this.StringLength = strLength;            DataSize = (byte)GetTypeLen(DataType);            DataSizeOfBits = _getBitLen(DataType);        }        private int GetTypeLen(Type type)        {            var bitLen = _getBitLen(type);            var mod = bitLen % 8;            if (mod > 0)                bitLen += 8 - mod;            return bitLen / 8;        }        private int _getBitLen(Type type)        {            if (type.IsArray)                return _getBitLen(type.GetElementType()) * ArrayLength;            if (type == typeof(bool))                return 1;            else if (type.IsEnum)                return Marshal.SizeOf(type.GetEnumUnderlyingType()) * 8;            else if (type == typeof(string))                return (StringLength + 2) * 8;            else            {                if (typeof(IList).IsAssignableFrom(type))                    return 0;                return Marshal.SizeOf(type) * 8;            }        }        public object Value        {            get { return getValue(); }            set            {                setValue(value);            }        }        protected abstract void setValue(object value);        protected abstract object getValue();        private bool ValueEquals(object obj1, object obj2)        {            if (!obj1.GetType().IsArray) return obj1.Equals(obj2);            var arr1 = obj1 as Array;            var arr2 = obj2 as Array;            if (arr2 == null)            {                return true;            }            return !arr1!.Cast<object>().Where((t, i) => !arr1.GetValue(i)!.Equals(arr2.GetValue(2))).Any();        }    }    public class PlcItem<T> : PlcItem    {        public PlcItem(string id, string name, DataBlock db, int start, byte arrLen = 1, byte strLen = 0) : base(id, name, db, typeof(T), start, arrLen, strLen)        {        }        public new T Value        {            get            {                return (T)base.Value;            }            set            {                base.Value = value;            }        }        protected override void setValue(object value)        {            int i = 0;            while (true)            {                try                {                    Db.Write<T>(Start, (T)value, StringLength, ArrayLength);                    return;                }                catch                {                    if (i >= 3)                        throw;                    else                    {                        i++;                        Thread.Sleep(100);                    }                }            }        }        protected override object getValue()        {            return Db.Read<T>(Start, StringLength, ArrayLength);        }    }}
 |