diff --git a/src/Luban.Client/Source/Net/GenClient.cs b/src/Luban.Client/Source/Net/GenClient.cs index 612a790..d765466 100644 --- a/src/Luban.Client/Source/Net/GenClient.cs +++ b/src/Luban.Client/Source/Net/GenClient.cs @@ -99,7 +99,7 @@ namespace Luban.Client.Common.Net private async Task OnGetImportFileOrDirectoryAsync(GetImportFileOrDirectory rpc) { - long t1 = TimeUtil.NowMillis; + long t1 = Bright.Time.TimeUtil.NowMillis; var file = rpc.Arg.FileOrDirName; var suffixes = rpc.Arg.InclusiveSuffixs; var re = new GetImportFileOrDirectoryRes() @@ -139,14 +139,14 @@ namespace Luban.Client.Common.Net s_logger.Error(e); } - s_logger.Trace(" GetImportFileOrDirectory file:{file} err:{err} cost:{time}", file, re.Err, TimeUtil.NowMillis - t1); + s_logger.Trace(" GetImportFileOrDirectory file:{file} err:{err} cost:{time}", file, re.Err, Bright.Time.TimeUtil.NowMillis - t1); Session.ReplyRpc(rpc, re); } private async Task OnGetInputFileAsync(GetInputFile rpc) { - long t1 = TimeUtil.NowMillis; + long t1 = Bright.Time.TimeUtil.NowMillis; var res = new GetInputFileRes() { Err = Luban.Common.EErrorCode.OK }; try { @@ -158,7 +158,7 @@ namespace Luban.Client.Common.Net { res.Err = Luban.Common.EErrorCode.READ_FILE_FAIL; } - s_logger.Info(" get input file:{file} err:{err} cost:{time}", rpc.Arg.File, res.Err, TimeUtil.NowMillis - t1); + s_logger.Info(" get input file:{file} err:{err} cost:{time}", rpc.Arg.File, res.Err, Bright.Time.TimeUtil.NowMillis - t1); Session.ReplyRpc(rpc, res); } diff --git a/src/Luban.Common/Source/Utils/ProfileTimer.cs b/src/Luban.Common/Source/Utils/ProfileTimer.cs index 70d65f3..2982b6d 100644 --- a/src/Luban.Common/Source/Utils/ProfileTimer.cs +++ b/src/Luban.Common/Source/Utils/ProfileTimer.cs @@ -22,13 +22,13 @@ namespace Luban.Common.Utils public void StartPhase(string name) { - phaseStack.Push(new Phase() { Name = name, StartTime = TimeUtil.NowMillis }); + phaseStack.Push(new Phase() { Name = name, StartTime = Bright.Time.TimeUtil.NowMillis }); } private Phase EndPhase() { var phase = phaseStack.Pop(); - phase.EndTime = TimeUtil.NowMillis; + phase.EndTime = Bright.Time.TimeUtil.NowMillis; phase.ElapseTime = phase.EndTime - phase.StartTime; return phase; } diff --git a/src/Luban.Common/Source/Utils/TimeUtil.cs b/src/Luban.Common/Source/Utils/TimeZoneUtil.cs similarity index 100% rename from src/Luban.Common/Source/Utils/TimeUtil.cs rename to src/Luban.Common/Source/Utils/TimeZoneUtil.cs diff --git a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs index a17f82d..f20830d 100644 --- a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs +++ b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs @@ -1,3 +1,4 @@ +using Bright.Collections; using Luban.Common.Utils; using Luban.Job.Cfg.Cache; using Luban.Job.Cfg.Datas; diff --git a/src/Luban.Job.Cfg/Source/Utils/DataLoaderUtil.cs b/src/Luban.Job.Cfg/Source/Utils/DataLoaderUtil.cs index 059b9dc..f3cd294 100644 --- a/src/Luban.Job.Cfg/Source/Utils/DataLoaderUtil.cs +++ b/src/Luban.Job.Cfg/Source/Utils/DataLoaderUtil.cs @@ -170,16 +170,16 @@ namespace Luban.Job.Cfg.Utils List exportTables = ass.Types.Values.Where(t => t is DefTable ct && ct.NeedExport).Select(t => (DefTable)t).ToList(); var genDataTasks = new List(); var outputDataFiles = new ConcurrentBag(); - long genDataStartTime = TimeUtil.NowMillis; + long genDataStartTime = Bright.Time.TimeUtil.NowMillis; foreach (DefTable c in exportTables) { var table = c; genDataTasks.Add(Task.Run(async () => { - long beginTime = TimeUtil.NowMillis; + long beginTime = Bright.Time.TimeUtil.NowMillis; await LoadTableAsync(agent, table, dataDir, patchName, patchDataDir, inputConvertDataDir); - long endTime = TimeUtil.NowMillis; + long endTime = Bright.Time.TimeUtil.NowMillis; if (endTime - beginTime > 100) { ctx.Info("====== load {0} cost {1} ms ======", table.FullName, (endTime - beginTime)); diff --git a/src/LubanAssistant/LubanAssistant.csproj b/src/LubanAssistant/LubanAssistant.csproj index f00812c..f6d4542 100644 --- a/src/LubanAssistant/LubanAssistant.csproj +++ b/src/LubanAssistant/LubanAssistant.csproj @@ -243,12 +243,18 @@ Source\Utils\LogUtil.cs + + Source\Common\TimeZoneUtil.cs + Source\Utils\TypeUtil.cs Source\Utils\XmlUtil.cs + + Source\Cache\ExcelTableValueTypeDefInfoCacheManager.cs + Source\DataConverters\FillSheetVisitor.cs @@ -501,6 +507,9 @@ Source\Validators\RefValidator.cs + + Source\Validators\ValidatorAttribute.cs + Source\Validators\ValidatorFactory.cs @@ -630,6 +639,9 @@ Source\TypeVisitors\ITypeFuncVisitor.cs + + Source\TypeVisitors\TypeActionVisitorAdaptor.cs + Source\Utils\DefUtil.cs @@ -659,6 +671,7 @@ Resources.resx + SettingsSingleFileGenerator @@ -669,6 +682,7 @@ Settings.settings True + diff --git a/src/LubanAssistant/Source/Common/ReflectionUtil.cs b/src/LubanAssistant/Source/Common/ReflectionUtil.cs new file mode 100644 index 0000000..fe5b291 --- /dev/null +++ b/src/LubanAssistant/Source/Common/ReflectionUtil.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Bright.Common +{ + public class ParamInfo + { + public Type Type { get; set; } + + public bool ChildType { get; set; } + } + + public class SignatureInfo + { + public Type ReturnType { get; set; } + +#pragma warning disable CA2227 // 集合属性应为只读 + public List Params { get; set; } +#pragma warning restore CA2227 // 集合属性应为只读 + + public Action Callback { get; set; } + + public bool CanBeStatic { get; set; } + } + + public class ReflectionException : Exception + { + public ReflectionException() + { + } + + public ReflectionException(string message) : base(message) + { + } + + public ReflectionException(string message, Exception innerException) : base(message, innerException) + { + } + + protected ReflectionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + + public static class ReflectionUtil + { + public static Type GetType(string name) + { + foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) + { + var type = a.GetType(name); + if (type != null) + { + return type; + } + } + return null; + } + + public static Type[] GetSubTypes(Assembly assembly, Type type) + { + return assembly.GetTypes().Where(t => type.IsAssignableFrom(t) && !t.IsAbstract).ToArray(); + } + + public static Type[] GetTypesByAttr(Assembly assembly, Type attr) + { + return assembly.GetTypes().Where(t => t.GetCustomAttribute(attr) != null).ToArray(); + } + + public static MethodInfo[] GetMethodsByAttr(Type type, Type attr, bool includeStatic = false) + { + var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; + if (includeStatic) + { + flags |= BindingFlags.Static; + } + return type.GetMethods(flags).Where(m => m.GetCustomAttribute(attr) != null).ToArray(); + } + + public static Type[] GetCallingSubTypes(Type type) + { + return GetSubTypes(Assembly.GetCallingAssembly(), type); + } + + public static Type[] GetCallingTypesByAttr(Type attr) + { + return GetTypesByAttr(Assembly.GetCallingAssembly(), attr); + } + + public static Type MakeGenericActionFromMethod(MethodInfo method) + { + var argTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); + return argTypes.Length switch + { + 0 => typeof(Action), + 1 => typeof(Action<>).MakeGenericType(argTypes), + 2 => typeof(Action<,>).MakeGenericType(argTypes), + 3 => typeof(Action<,,>).MakeGenericType(argTypes), + 4 => typeof(Action<,,,>).MakeGenericType(argTypes), + 5 => typeof(Action<,,,,>).MakeGenericType(argTypes), + _ => throw new NotImplementedException(), + }; + } + + public static Type MakeGenericFuncFromMethod(MethodInfo method) + { + var returnType = method.ReturnType; + var argTypes = method.GetParameters().Select(p => p.ParameterType).Concat(new Type[] { returnType }).ToArray(); + return argTypes.Length switch + { + 1 => typeof(Func<>).MakeGenericType(argTypes), + 2 => typeof(Func<,>).MakeGenericType(argTypes), + 3 => typeof(Func<,,>).MakeGenericType(argTypes), + 4 => typeof(Func<,,,>).MakeGenericType(argTypes), + 5 => typeof(Func<,,,,>).MakeGenericType(argTypes), + 6 => typeof(Func<,,,,,>).MakeGenericType(argTypes), + _ => throw new NotImplementedException(), + }; + } + + + + public static void ScanHandler(Type type, object self, Type attr, params SignatureInfo[] signatures) + { + foreach (var method in GetMethodsByAttr(type, attr, true)) + { + bool match = false; + foreach (var s in signatures) + { + var ps = method.GetParameters(); + if (method.ReturnType == s.ReturnType && ps.Length == s.Params.Count) + { + bool allMatch = true; + for (int i = 0; i < ps.Length; i++) + { + var p = s.Params[i]; + if ((p.ChildType ? !p.Type.IsAssignableFrom(ps[i].ParameterType) : p.Type != ps[i].ParameterType)) + { + allMatch = false; + break; + } + } + if (!allMatch) + { + continue; + } + + if (allMatch && method.IsStatic && !s.CanBeStatic) + { + throw new ReflectionException($"type:{type} method:{method} can't be static"); + } + match = true; + + var del = Delegate.CreateDelegate((method.ReturnType == typeof(void) ? MakeGenericActionFromMethod(method) : MakeGenericFuncFromMethod(method)), + method.IsStatic ? null : self, method); + s.Callback(del, method.GetCustomAttribute(attr)); + break; + } + } + if (!match) + { + throw new ReflectionException($"type{type} method:{method} invalid signature"); + } + } + } + + public static Action CastAction(Delegate del) where TS : TR + { + var action = (Action)del; + return (TR a) => action((TS)a); + } + + + //public static Action CastAction(Delegate del, Type sourceType) + //{ + // var castAction = typeof(ReflectionUtil).GetMethod(nameof(CastAction), 2, new Type[] { typeof(Delegate) }); + // return (Action)castAction.MakeGenericMethod(sourceType, typeof(TR)).Invoke(null, new object[] { del }); + //} + + public static Action CastAction(Delegate del) where TS1 : TR1 where TS2 : TR2 + { + var action = (Action)del; + return (TR1 a, TR2 b) => action((TS1)a, (TS2)b); + } + + public static Action CastAction(Delegate del) where TS1 : TR1 where TS2 : TR2 where TS3 : TR3 + { + var action = (Action)del; + return (TR1 a, TR2 b, TR3 c) => action((TS1)a, (TS2)b, (TS3)c); + } + + //public static void RegisterProtoHandler(Assembly assembly, HandlerDispatcher dispatcher) + //{ + // foreach (var type in GetTypesByAttr(assembly, typeof(ProtoHandlerAttribute))) + // { + // var handler = (ProtoHandler)Activator.CreateInstance(type); + // s_logger.ConditionalDebug("RegisterProtoHandler {0} {1}", type, handler); + // dispatcher.Register(type.BaseType.GetGenericArguments()[0], handler.Process); + // } + //} + } +}