DataField.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using System.Collections;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. namespace WCS.Core
  7. {
  8. public delegate void ValueChangedHandler<T>(PlcItem<T> sender, T value);
  9. public delegate void ValueChangedHandler(PlcItem sender, object value);
  10. public abstract class PlcItem
  11. {
  12. protected DataBlock Db;
  13. public int Start;//按位计算 如,第2个字节,Start=8
  14. public byte ArrayLength, StringLength;
  15. public string Id;
  16. public string Name;
  17. public string IP;
  18. public ushort DB;
  19. public Type DataType { get; private set; }
  20. /// <summary>
  21. /// 数据类型所占的字节数
  22. /// </summary>
  23. public byte DataSize { get; private set; }
  24. public int DataSizeOfBits { get; private set; }
  25. public PlcItem(string id, string name, DataBlock db, Type type, int start, byte arrLen = 1, byte strLength = 0)
  26. {
  27. this.Id = id;
  28. this.Name = name;
  29. this.Db = db;
  30. this.DataType = type;
  31. //this.Db.DBChanged += Db_DBChanged;
  32. this.Start = start;
  33. this.ArrayLength = arrLen;
  34. this.StringLength = strLength;
  35. DataSize = (byte)GetTypeLen(DataType);
  36. DataSizeOfBits = _getBitLen(DataType);
  37. }
  38. private int GetTypeLen(Type type)
  39. {
  40. var bitLen = _getBitLen(type);
  41. var mod = bitLen % 8;
  42. if (mod > 0)
  43. bitLen += 8 - mod;
  44. return bitLen / 8;
  45. }
  46. private int _getBitLen(Type type)
  47. {
  48. if (type.IsArray)
  49. return _getBitLen(type.GetElementType()) * ArrayLength;
  50. if (type == typeof(bool))
  51. return 1;
  52. else if (type.IsEnum)
  53. return Marshal.SizeOf(type.GetEnumUnderlyingType()) * 8;
  54. else if (type == typeof(string))
  55. return (StringLength + 2) * 8;
  56. else
  57. {
  58. if (typeof(IList).IsAssignableFrom(type))
  59. return 0;
  60. return Marshal.SizeOf(type) * 8;
  61. }
  62. }
  63. public object Value
  64. {
  65. get { return getValue(); }
  66. set
  67. {
  68. setValue(value);
  69. }
  70. }
  71. protected abstract void setValue(object value);
  72. protected abstract object getValue();
  73. private bool ValueEquals(object obj1, object obj2)
  74. {
  75. if (!obj1.GetType().IsArray) return obj1.Equals(obj2);
  76. var arr1 = obj1 as Array;
  77. var arr2 = obj2 as Array;
  78. if (arr2 == null)
  79. {
  80. return true;
  81. }
  82. return !arr1!.Cast<object>().Where((t, i) => !arr1.GetValue(i)!.Equals(arr2.GetValue(2))).Any();
  83. }
  84. }
  85. public class PlcItem<T> : PlcItem
  86. {
  87. 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)
  88. {
  89. }
  90. public new T Value
  91. {
  92. get
  93. {
  94. return (T)base.Value;
  95. }
  96. set
  97. {
  98. base.Value = value;
  99. }
  100. }
  101. protected override void setValue(object value)
  102. {
  103. int i = 0;
  104. while (true)
  105. {
  106. try
  107. {
  108. Db.Write<T>(Start, (T)value, StringLength, ArrayLength);
  109. return;
  110. }
  111. catch
  112. {
  113. if (i >= 3)
  114. throw;
  115. else
  116. {
  117. i++;
  118. Thread.Sleep(100);
  119. }
  120. }
  121. }
  122. }
  123. protected override object getValue()
  124. {
  125. return Db.Read<T>(Start, StringLength, ArrayLength);
  126. }
  127. }
  128. }