123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- 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
- {
- 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 int 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 = 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;
- 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;
- }
- public object Value
- {
- get => 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;
- if (obj2 is Array arr2)
- {
- return !arr1.Cast<object>().Where((t, i) => !arr1.GetValue(i).Equals(arr2.GetValue(2))).Any();
- }
- return true;
- }
- else
- {
- 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
- {
- if (i >= 3) throw;
- i++;
- Thread.Sleep(100);
- }
- }
- }
- protected override object getValue()
- {
- return Db.Read<T>(Start, StringLength, ArrayLength);
- }
- }
- }
|