123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- using System.ComponentModel.DataAnnotations;
- using System.Reflection;
- using System.Runtime.InteropServices;
- namespace WCS.Core
- {
- public abstract class ProtocolProxyBase : IProtocolProxy
- {
- private string Id = Guid.NewGuid().ToString();
- public ProtocolInfo Info { get; private set; }
- public int BytesCount { get; private set; }
- public Dictionary<string, PlcItem> Items = new Dictionary<string, PlcItem>();
- public Type ProtocolType, ProtocolDataType;
- public Device Device { get; private set; }
- public World World { get; private set; }
- public DataBlock Db { get; private set; }
- public DateTime Frame;
- public ProtocolProxyBase(Device dev, ProtocolInfo info, Type protocolType, World world)
- {
- this.World= world;
- this.Frame = world.Frame;
- this.Device = dev;
- this.Info = info;
- Db = info.DBInfo.Ex(world);
- Db.DbChanged += Db_DbChanged;
- ProtocolType = protocolType;
- var bitStart = info.Position * 8;//偏移量,按位算
- //this.Start = start;
- //PlcDB db = new PlcDB(null, 50, 100);
- var lst = this.GetType().GetInterfaces().ToList();
- var ps = lst.SelectMany(v => v.GetProperties()).ToArray();
- foreach (var p in ps)
- {
- if (p.GetIndexParameters().Length > 0) continue;
- if (typeof(ProtocolProxyBase).GetProperty(p.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null) continue;
- #region 计算偏移量
- var modeNum = 0;
- var t = p.PropertyType;
- if (t.IsEnum)
- t = t.GetEnumUnderlyingType();
- if (t == typeof(bool))//bit类型,db块中无须补齐16位
- {
- modeNum = 1;
- }
- else if (t.IsPrimitive && Marshal.SizeOf(t) == 1)//byte char 等单字节类型,db块中无须补齐16位
- {
- modeNum = 8;
- }
- else//其他类型,db块中必须补齐16位
- {
- modeNum = 16;
- }
- var mod = bitStart % modeNum;
- if (mod > 0)
- {
- bitStart += modeNum - mod;
- }
- #endregion 计算偏移量
- byte arrlen = 0;
- byte strLen = 0;
- if (t.IsArray)
- {
- var attr = p.GetCustomAttributes(typeof(MaxLengthAttribute), true).FirstOrDefault() as MaxLengthAttribute;
- if (attr != null)
- arrlen = (byte)attr.Length;
- }
- else if (p.PropertyType == typeof(string))
- {
- var attr = p.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
- strLen = (byte)attr.MaximumLength;
- }
- var m = typeof(DataBlock).GetMethod("Regist");
- m = m.MakeGenericMethod(p.PropertyType);
- var item = m.Invoke(Db, new object[] { this, Id, p.Name, bitStart, arrlen, strLen }) as PlcItem;
- Items.Add(p.Name, item);
- bitStart += item.DataSizeOfBits;
- BytesCount += item.DataSize;
- }
- ProtocolDataType = ProtocolType.Assembly.GetTypes().Where(v => v.IsClass).First(v => v.GetInterface(ProtocolType.Name) != null && v != this.GetType());
- }
- private byte[] Data = new byte[0];
- private void Db_DbChanged(byte[] data)
- {
- var pos = Info.Position - Db.Start;
- var bytes = data.Skip(pos).Take(BytesCount).ToArray();
- if (Data.SequenceEqual(bytes))
- return;
- this.Frame = World.Frame;
- Data = bytes;
- DataChanged();
- }
- protected abstract void DataChanged();
- #region
- public void AddEvent(string eventName, Delegate delgate)
- {
- throw new NotImplementedException();
- }
- public void RemoveEvent(string eventName, Delegate delgate)
- {
- throw new NotImplementedException();
- }
- public T CallReturn<T>(string methodName, params object[] args)
- {
- throw new NotImplementedException();
- }
- public void CallVoid(string methodName, params object[] args)
- {
- throw new NotImplementedException();
- }
- public T Get<T>(string propertyName)
- {
- var item = Items[propertyName] as PlcItem<T>;
- var res = item.Value;
- var channel = Ltc.GetChannel();
- //if (channel != null)
- //this.World.OnInternalLog(channel, $"获取{Device.Code}.{ProtocolType.Name}.{propertyName} 值:{res}");
- return res;
- }
- public void Set<T>(string propertyName, T value)
- {
- var item = Items[propertyName] as PlcItem<T>;
- item.Value = value;
- var channel = Ltc.GetChannel();
- if (channel != null)
- this.World.OnInternalLog(channel, $"设置值:{Device.Code}.{ProtocolType.Name}.{propertyName}值:{value}");
- this.Frame = World.Frame;
- DataChanged();
- }
- #endregion
- }
- }
|