using System; using System.Collections; using System.Runtime.InteropServices; using System.Threading; namespace WCS.Core { public delegate void ValueChangedHandler(PlcItem 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; } /// /// 数据类型所占的字节数 /// 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 object lastValue; private bool ValueEquals(object obj1, object obj2) { if (obj1.GetType().IsArray) { var arr1 = obj1 as Array; var arr2 = obj2 as Array; if (arr2 == null) { return true; } for (int i = 0; i < arr1.Length; i++) { if (!arr1.GetValue(i).Equals(arr2.GetValue(2))) return false; } return true; } else { return obj1.Equals(obj2); } } } public class PlcItem : 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(Start, (T)value, StringLength, ArrayLength); return; } catch { if (i >= 3) throw; else { i++; Thread.Sleep(100); } } } } protected override object getValue() { return Db.Read(Start, StringLength, ArrayLength); } } }