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