DataField.cs 4.2 KB

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