DataField.cs 4.2 KB

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