From 704b2b75f462641f0d69076acb9f0a884349ba13 Mon Sep 17 00:00:00 2001 From: FiniteReality Date: Fri, 25 Nov 2016 20:22:06 +0000 Subject: [PATCH] Fix changes after review --- .../Builders/ModuleClassBuilder.cs | 19 ++-- .../Builders/ParameterBuilder.cs | 2 +- src/Discord.Net.Commands/CommandService.cs | 94 ++++++++++--------- src/Discord.Net.Commands/Info/CommandInfo.cs | 23 ++--- 4 files changed, 66 insertions(+), 72 deletions(-) diff --git a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs index aaa96fb8e..e8dc60de8 100644 --- a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs @@ -183,9 +183,7 @@ namespace Discord.Commands if (attribute is SummaryAttribute) builder.Summary = (attribute as SummaryAttribute).Text; else if (attribute is OverrideTypeReaderAttribute) - { builder.TypeReader = GetTypeReader(service, paramType, (attribute as OverrideTypeReaderAttribute).TypeReader); - } else if (attribute is ParameterPreconditionAttribute) builder.AddPrecondition(attribute as ParameterPreconditionAttribute); else if (attribute is ParamArrayAttribute) @@ -204,8 +202,7 @@ namespace Discord.Commands if (builder.TypeReader == null) { - var readers = service.GetTypeReaders(paramType); - var reader = readers?.FirstOrDefault(); + var reader = service.GetDefaultTypeReader(paramType); if (reader == null) { @@ -229,20 +226,16 @@ namespace Discord.Commands private static TypeReader GetTypeReader(CommandService service, Type paramType, Type typeReaderType) { var readers = service.GetTypeReaders(paramType); + TypeReader reader = null; if (readers != null) - { - var reader = readers.FirstOrDefault(x => x.GetType() == typeReaderType); - if (reader != default(TypeReader)) - { + if (readers.TryGetValue(typeReaderType, out reader)) return reader; - } - } //could not find any registered type reader: try to create one - var typeReader = ReflectionUtils.CreateObject(typeReaderType.GetTypeInfo(), service, DependencyMap.Empty); - service.AddTypeReader(paramType, typeReader); + reader = ReflectionUtils.CreateObject(typeReaderType.GetTypeInfo(), service, DependencyMap.Empty); + service.AddTypeReader(paramType, reader); - return typeReader; + return reader; } private static bool IsValidModuleDefinition(TypeInfo typeInfo) diff --git a/src/Discord.Net.Commands/Builders/ParameterBuilder.cs b/src/Discord.Net.Commands/Builders/ParameterBuilder.cs index 89f89b3cf..d4cf598ec 100644 --- a/src/Discord.Net.Commands/Builders/ParameterBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ParameterBuilder.cs @@ -46,7 +46,7 @@ namespace Discord.Commands.Builders if (readers == null) throw new InvalidOperationException($"{type} does not have a TypeReader registered for it"); - TypeReader = readers.FirstOrDefault(); + TypeReader = readers.FirstOrDefault().Value; if (type.GetTypeInfo().IsValueType) DefaultValue = Activator.CreateInstance(type); diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 285a35432..3dc1ca5d6 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -14,8 +14,9 @@ namespace Discord.Commands public class CommandService { private readonly SemaphoreSlim _moduleLock; - private readonly ConcurrentDictionary _typedModuleDefs; - private readonly ConcurrentDictionary> _typeReaders; + private readonly ConcurrentDictionary _typedModuleDefs; + private readonly ConcurrentDictionary> _typeReaders; + private readonly ConcurrentDictionary _defaultTypeReaders; private readonly ConcurrentBag _moduleDefs; private readonly CommandMap _map; @@ -24,7 +25,7 @@ namespace Discord.Commands public IEnumerable Modules => _moduleDefs.Select(x => x); public IEnumerable Commands => _moduleDefs.SelectMany(x => x.Commands); - public ILookup TypeReaders => _typeReaders.SelectMany(x => x.Value, (a, value) => new {a.Key, value}).ToLookup(x => x.Key, x => x.value); + public ILookup TypeReaders => _typeReaders.SelectMany(x => x.Value.Select(y => new {y.Key, y.Value})).ToLookup(x => x.Key, x => x.Value); public CommandService() : this(new CommandServiceConfig()) { } public CommandService(CommandServiceConfig config) @@ -33,41 +34,43 @@ namespace Discord.Commands _typedModuleDefs = new ConcurrentDictionary(); _moduleDefs = new ConcurrentBag(); _map = new CommandMap(); - _typeReaders = new ConcurrentDictionary> + _typeReaders = new ConcurrentDictionary>(); + + _defaultTypeReaders = new ConcurrentDictionary { - [typeof(bool)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(char)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(string)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(byte)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(sbyte)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(ushort)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(short)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(uint)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(int)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(ulong)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(long)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(float)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(double)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(decimal)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(DateTime)] = new ConcurrentBag{new SimpleTypeReader()}, - [typeof(DateTimeOffset)] = new ConcurrentBag{new SimpleTypeReader()}, + [typeof(bool)] = new SimpleTypeReader(), + [typeof(char)] = new SimpleTypeReader(), + [typeof(string)] = new SimpleTypeReader(), + [typeof(byte)] = new SimpleTypeReader(), + [typeof(sbyte)] = new SimpleTypeReader(), + [typeof(ushort)] = new SimpleTypeReader(), + [typeof(short)] = new SimpleTypeReader(), + [typeof(uint)] = new SimpleTypeReader(), + [typeof(int)] = new SimpleTypeReader(), + [typeof(ulong)] = new SimpleTypeReader(), + [typeof(long)] = new SimpleTypeReader(), + [typeof(float)] = new SimpleTypeReader(), + [typeof(double)] = new SimpleTypeReader(), + [typeof(decimal)] = new SimpleTypeReader(), + [typeof(DateTime)] = new SimpleTypeReader(), + [typeof(DateTimeOffset)] = new SimpleTypeReader(), - [typeof(IMessage)] = new ConcurrentBag{new MessageTypeReader()}, - [typeof(IUserMessage)] = new ConcurrentBag{new MessageTypeReader()}, - [typeof(IChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IDMChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IGroupChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IGuildChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IMessageChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IPrivateChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(ITextChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - [typeof(IVoiceChannel)] = new ConcurrentBag{new ChannelTypeReader()}, - - [typeof(IRole)] = new ConcurrentBag{new RoleTypeReader()}, - - [typeof(IUser)] = new ConcurrentBag{new UserTypeReader()}, - [typeof(IGroupUser)] = new ConcurrentBag{new UserTypeReader()}, - [typeof(IGuildUser)] = new ConcurrentBag{new UserTypeReader()}, + [typeof(IMessage)] = new MessageTypeReader(), + [typeof(IUserMessage)] = new MessageTypeReader(), + [typeof(IChannel)] = new ChannelTypeReader(), + [typeof(IDMChannel)] = new ChannelTypeReader(), + [typeof(IGroupChannel)] = new ChannelTypeReader(), + [typeof(IGuildChannel)] = new ChannelTypeReader(), + [typeof(IMessageChannel)] = new ChannelTypeReader(), + [typeof(IPrivateChannel)] = new ChannelTypeReader(), + [typeof(ITextChannel)] = new ChannelTypeReader(), + [typeof(IVoiceChannel)] = new ChannelTypeReader(), + + [typeof(IRole)] = new RoleTypeReader(), + + [typeof(IUser)] = new UserTypeReader(), + [typeof(IGroupUser)] = new UserTypeReader(), + [typeof(IGuildUser)] = new UserTypeReader(), }; _caseSensitive = config.CaseSensitiveCommands; _defaultRunMode = config.DefaultRunMode; @@ -197,21 +200,28 @@ namespace Discord.Commands //Type Readers public void AddTypeReader(TypeReader reader) { - var readers = _typeReaders.GetOrAdd(typeof(T), x => new ConcurrentBag()); - readers.Add(reader); + var readers = _typeReaders.GetOrAdd(typeof(T), x => new ConcurrentDictionary()); + readers[reader.GetType()] = reader; } public void AddTypeReader(Type type, TypeReader reader) { - var readers = _typeReaders.GetOrAdd(type, x=> new ConcurrentBag()); - readers.Add(reader); + var readers = _typeReaders.GetOrAdd(type, x=> new ConcurrentDictionary()); + readers[reader.GetType()] = reader; } - internal IEnumerable GetTypeReaders(Type type) + internal IDictionary GetTypeReaders(Type type) { - ConcurrentBag definedTypeReaders; + ConcurrentDictionary definedTypeReaders; if (_typeReaders.TryGetValue(type, out definedTypeReaders)) return definedTypeReaders; return null; } + internal TypeReader GetDefaultTypeReader(Type type) + { + TypeReader reader; + if (_defaultTypeReaders.TryGetValue(type, out reader)) + return reader; + return null; + } //Execution public SearchResult Search(CommandContext context, int argPos) => Search(context, context.Message.Content.Substring(argPos)); diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index a91a1f9f4..a6ac50005 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -135,26 +135,17 @@ namespace Discord.Commands if (map == null) map = DependencyMap.Empty; - object[] args = null; - try { - args = GenerateArgs(argList, paramList); - } - catch (Exception ex) - { - return ExecuteResult.FromError(ex); - } + object[] args = GenerateArgs(argList, paramList); - foreach (var parameter in Parameters) - { - var result = await parameter.CheckPreconditionsAsync(context, args, map).ConfigureAwait(false); - if (!result.IsSuccess) - return ExecuteResult.FromError(result); - } + foreach (var parameter in Parameters) + { + var result = await parameter.CheckPreconditionsAsync(context, args, map).ConfigureAwait(false); + if (!result.IsSuccess) + return ExecuteResult.FromError(result); + } - try - { switch (RunMode) { case RunMode.Sync: //Always sync