| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 | using System.Collections.Concurrent;using System.Text.Json.Serialization;namespace WCS.Core{    public class EntityEx<T>    {        public T Entity { get; private set; }        public EntityEx(T ent)        {            this.Entity = ent;        }    }    public class Device    {        private static ConcurrentDictionary<string, Device> all = new ConcurrentDictionary<string, Device>();        public static IEnumerable<Device> 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<string, ProtocolInfo> Protocols { get; private set; } = new Dictionary<string, ProtocolInfo>();        public Device(string code)        {            if (all.ContainsKey(code))                throw new Exception($"{code}设备号重复");            this.Code = code;            all[code] = this;        }        private ConcurrentDictionary<Type, object> ProtocolObjs(World world)        {            if (!ProtocolObjsOfWorld.TryGetValue(world, out var pobjs))            {                pobjs = new ConcurrentDictionary<Type, object>();                ProtocolObjsOfWorld[world] = pobjs;            }            return pobjs;        }        private ConcurrentDictionary<World, ConcurrentDictionary<Type, object>> ProtocolObjsOfWorld = new ConcurrentDictionary<World, ConcurrentDictionary<Type, object>>();        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", 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<Device> Targets        {            get            {                return GetFlags("Target").Select(v => Device.all[v]).ToList();            }        }        [JsonIgnore]        public IEnumerable<Device> Sources        {            get            {                return Device.All.Where(v => v.GetFlags("Target").Contains(this.Code)).ToArray();            }        }        /// <summary>        ///  设备组        /// </summary>        [JsonIgnore]        public IEnumerable<Device> DeviceGroup        {            get            {                return GetFlags("DeviceGroup").Select(v => Device.all[v]).ToList();            }        }        /// <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($"{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<string, List<string>> Flags { get; private set; } = new Dictionary<string, List<string>>();        public void AddFlag(string key, string flag)        {            if (!Flags.ContainsKey(key))                Flags[key] = new List<string>();            Flags[key].Add(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 void AddFlag(string flag)        {            SetFlag("Globals", flag);        }        public bool HasFlag(string flag)        {            return HasFlag("Globals", flag);        }        public void 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);            }        }        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 T Data { get; set; }        public Device(Device device, World world) : base(device)        {            Data = Entity.Protocol<T>(world);        }        public override string ToString()        {            return Entity.Code;        }    }    public class Device<T, T2> : Device<T>    {        public T2 Data2 { get; set; }        public Device(Device device, World world) : base(device, world)        {            Data2 = Entity.Protocol<T2>(world);        }    }    public class Device<T, T2, T3> : Device<T, T2>    {        public T3 Data3 { get; set; }        public Device(Device device, World world) : base(device, world)        {            Data3 = Entity.Protocol<T3>(world);        }    }    public class Device<T, T2, T3, T4> : Device<T, T2, T3>    {        public T4 Data4 { get; set; }        public Device(Device device, World world) : base(device, world)        {            Data4 = Entity.Protocol<T4>(world);        }    }    public class Device<T, T2, T3, T4, T5> : Device<T, T2, T3, T4>    {        public T5 Data5 { get; set; }        public Device(Device device, World world) : base(device, world)        {            Data5 = Entity.Protocol<T5>(world);        }    }    public class Device<T, T2, T3, T4, T5, T6> : Device<T, T2, T3, T4, T5>    {        public T6 Data6 { get; set; }        public Device(Device device, World world) : base(device, world)        {            Data6 = Entity.Protocol<T6>(world);        }    }}
 |