| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | using System.Collections;using System.Runtime.InteropServices;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{    public byte ArrayLength, StringLength;    protected DataBlock Db;    public ushort DB;    public string Id;    public string IP;    private object lastValue;    public string Name;    public int Start; //按位计算 如,第2个字节,Start=8    public PlcItem(string id, string name, DataBlock db, Type type, int start, byte arrLen = 1, byte strLength = 0)    {        Id = id;        Name = name;        Db = db;        DataType = type;        //this.Db.DBChanged += Db_DBChanged;        Start = start;        ArrayLength = arrLen;        StringLength = strLength;        DataSize = GetTypeLen(DataType);        DataSizeOfBits = _getBitLen(DataType);    }    public Type DataType { get; }    /// <summary>    ///     数据类型所占的字节数    /// </summary>    public int DataSize { get; private set; }    public int DataSizeOfBits { get; private set; }    public object Value    {        get => getValue();        set => setValue(value);    }    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;        if (type.IsEnum) return Marshal.SizeOf(type.GetEnumUnderlyingType()) * 8;        if (type == typeof(string)) return StringLength * 8;        if (typeof(IList).IsAssignableFrom(type)) return 0;        return Marshal.SizeOf(type) * 8;    }    protected abstract void setValue(object value);    protected abstract object getValue();    private bool ValueEquals(object obj1, object obj2)    {        if (obj1.GetType().IsArray)        {            var arr1 = obj1 as Array;            if (obj2 is Array arr2)                return !arr1.Cast<object>().Where((t, i) => !arr1.GetValue(i).Equals(arr2.GetValue(2))).Any();            return true;        }        return obj1.Equals(obj2);    }}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 => (T)base.Value;        set => base.Value = value;    }    protected override void setValue(object value)    {        var i = 0;        while (true)            try            {                Db.Write<T>(Start, (T)value, StringLength, ArrayLength);                return;            }            catch (Exception ex)            {                if (i >= 3)                    throw new Exception(                        $"写入出错{ex.Message}--{Start}--{(T)value}--{StringLength}--{ArrayLength}--{Db.Entity.No}");                i++;                Thread.Sleep(100);            }    }    protected override object getValue()    {        return Db.Read<T>(Start, StringLength, ArrayLength);    }}
 |