123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- using System.Collections.Concurrent;
- using System.Reflection;
- using System.Text.Json.Serialization;
- namespace WCS.Core;
- public class EntityEx<T>
- {
- public EntityEx(T ent)
- {
- Entity = ent;
- }
- public T Entity { get; }
- public override string ToString()
- {
- return Entity.ToString();
- }
- }
- public class Device
- {
- private static readonly ConcurrentDictionary<string, Device> all = new();
- private readonly ConcurrentDictionary<World, ConcurrentDictionary<Type, object>> ProtocolObjsOfWorld = new();
- public Device(string code)
- {
- if (all.ContainsKey(code))
- throw new Exception($"{code}设备号重复");
- Code = code;
- all[code] = this;
- }
- public static IEnumerable<Device> All => all.Values;
- public string Code { get; set; } = "";
- public Dictionary<string, ProtocolInfo> Protocols { get; } = new();
- [JsonIgnore]
- public IEnumerable<Device> Targets
- {
- get { return GetFlags("Target").Select(v => all[v]).ToList(); }
- }
- [JsonIgnore]
- public IEnumerable<Device> Sources
- {
- get { return All.Where(v => v.GetFlags("Target").Contains(Code)).ToArray(); }
- }
- /// <summary>
- /// 设备组
- /// </summary>
- [JsonIgnore]
- public IEnumerable<Device> DeviceGroup
- {
- get { return GetFlags("DeviceGroup").Select(v => all[v]).ToList(); }
- }
- [JsonIgnore]
- public Device? Parent
- {
- get
- {
- var code = GetFlag("Parent");
- if (string.IsNullOrEmpty(code))
- return null;
- return Find(code);
- }
- set => SetFlag("Parent", value.Code);
- }
- public Dictionary<string, List<string>> Flags { get; } = new();
- public static Device Find(string code)
- {
- if (all.TryGetValue(code, out var dev))
- return dev;
- throw new Exception($"未找到设备{code}");
- }
- public ConcurrentDictionary<Type, object> ProtocolObjs(World world)
- {
- if (!ProtocolObjsOfWorld.TryGetValue(world, out var pobjs))
- {
- pobjs = new ConcurrentDictionary<Type, object>();
- ProtocolObjsOfWorld[world] = pobjs;
- }
- return pobjs;
- }
- public void AddProtocol(Type type, ProtocolInfo info)
- {
- if (!Protocols.TryAdd(type.AssemblyQualifiedName, info))
- throw new Exception($"{Code}重复添加协议{type.Name}");
- }
- public void AddProtocol<T>(ProtocolInfo info)
- {
- AddProtocol(typeof(T), info);
- }
- public bool HasProtocol(Type type)
- {
- return Protocols.ContainsKey(type.AssemblyQualifiedName);
- }
- public bool HasProtocol<T>()
- {
- return HasProtocol(typeof(T));
- }
- public T Protocol<T>(World world)
- {
- return (T)Protocol(typeof(T), world);
- }
- public object Protocol(Type protocolType, World world)
- {
- if (!HasProtocol(protocolType))
- throw new Exception($"{Code}不包含协议:{protocolType.Name}");
- if (!ProtocolObjs(world).ContainsKey(protocolType))
- {
- var type = typeof(Generator<,>);
- type = type.MakeGenericType(protocolType, Configs.ProtocolProxyBaseType);
- var m = type.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
- var info = Protocols[protocolType.AssemblyQualifiedName];
- var obj = m.Invoke(null, new object[] { new object[] { this, info, protocolType, world } });
- ProtocolObjs(world)[protocolType] = obj;
- }
- return ProtocolObjs(world)[protocolType];
- }
- public override string ToString()
- {
- return Code;
- }
- /// <summary>
- /// 添加设备组信息
- /// </summary>
- /// <param name="codes"></param>
- /// <exception cref="Exception"></exception>
- public void AddDeviceGroup(params string[] codes)
- {
- foreach (var code in codes)
- {
- if (HasFlag("DeviceGroup", code))
- throw new Exception($"{Code}子设备:{code}");
- AddFlag("DeviceGroup", code);
- }
- }
- public void AddTarget(params string[] codes)
- {
- foreach (var code in codes)
- {
- if (HasFlag("Target", code))
- throw new Exception($"{Code}已经存在目的地:{code}");
- AddFlag("Target", code);
- }
- }
- public Device AddFlag(string key, string flag)
- {
- if (!Flags.ContainsKey(key))
- Flags[key] = new List<string>();
- Flags[key].Add(flag);
- return this;
- }
- public void SetFlag(string flag)
- {
- SetFlag("Globals", flag);
- }
- public void SetFlag(string key, string flag)
- {
- var list = new List<string>();
- list.Add(flag);
- Flags[key] = list;
- }
- public IEnumerable<string> GetFlags(string key)
- {
- if (!Flags.ContainsKey(key))
- return new List<string>();
- return Flags[key];
- }
- public string? GetFlag(string key)
- {
- return GetFlags(key).FirstOrDefault();
- }
- public bool HasFlag(string key, string flag)
- {
- if (!Flags.ContainsKey(key))
- return false;
- return Flags[key].Contains(flag);
- }
- public bool HasFlag(string flag)
- {
- return HasFlag("Globals", flag);
- }
- public Device AddFlag<T>(T flag) where T : struct, Enum
- {
- var key = typeof(T).AssemblyQualifiedName;
- if (Flags.ContainsKey(key))
- {
- dynamic value = Enum.Parse<T>(Flags[key].First());
- var str = (value | flag).ToString();
- SetFlag(key, str);
- }
- else
- {
- var str = flag.ToString();
- SetFlag(key, str);
- }
- return this;
- }
- public bool HasFlag<T>(T flag) where T : struct, Enum
- {
- var key = typeof(T).AssemblyQualifiedName;
- if (!Flags.ContainsKey(key))
- return false;
- dynamic value = Enum.Parse<T>(Flags[key].First());
- return value.HasFlag(flag);
- }
- }
- public class Device<T> : EntityEx<Device>
- {
- public Device(Device device, World world) : base(device)
- {
- World = world;
- Data = Entity.Protocol<T>(world);
- }
- public World World { get; private set; }
- public T Data { get; set; }
- public override string ToString()
- {
- return Entity.Code;
- }
- }
- public class Device<T, T2> : Device<T>
- {
- public Device(Device device, World world) : base(device, world)
- {
- Data2 = Entity.Protocol<T2>(world);
- }
- public T2 Data2 { get; set; }
- }
- public class Device<T, T2, T3> : Device<T, T2>
- {
- public Device(Device device, World world) : base(device, world)
- {
- Data3 = Entity.Protocol<T3>(world);
- }
- public T3 Data3 { get; set; }
- }
- public class Device<T, T2, T3, T4> : Device<T, T2, T3>
- {
- public Device(Device device, World world) : base(device, world)
- {
- Data4 = Entity.Protocol<T4>(world);
- }
- public T4 Data4 { get; set; }
- }
- public class Device<T, T2, T3, T4, T5> : Device<T, T2, T3, T4>
- {
- public Device(Device device, World world) : base(device, world)
- {
- Data5 = Entity.Protocol<T5>(world);
- }
- public T5 Data5 { get; set; }
- }
- public class Device<T, T2, T3, T4, T5, T6> : Device<T, T2, T3, T4, T5>
- {
- public Device(Device device, World world) : base(device, world)
- {
- Data6 = Entity.Protocol<T6>(world);
- }
- public T6 Data6 { get; set; }
- }
|