diff --git a/src/Discord.Net.Commands/CommandMap.cs b/src/Discord.Net.Commands/CommandMap.cs new file mode 100644 index 000000000..f99073189 --- /dev/null +++ b/src/Discord.Net.Commands/CommandMap.cs @@ -0,0 +1,71 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Discord.Commands +{ + public class CommandMap + { + private readonly ConcurrentDictionary> _map; + + public CommandMap() + { + _map = new ConcurrentDictionary>(); + } + + public void Add(string key, Command cmd) + { + var list = _map.GetOrAdd(key, _ => new List()); + lock (list) + list.Add(cmd); + } + public void Remove(string key, Command cmd) + { + List list; + if (_map.TryGetValue(key, out list)) + { + lock (list) + list.Remove(cmd); + } + } + public IReadOnlyList Get(string key) + { + List list; + if (_map.TryGetValue(key, out list)) + { + lock (list) + return list.ToImmutableArray(); + } + return ImmutableArray.Create(); + } + + //TODO: C#7 Candidate for tuple + public CommandSearchResults Search(string input) + { + string lowerInput = input.ToLowerInvariant(); + + List bestGroup = null, group; + int startPos = 0, endPos; + + while (true) + { + endPos = input.IndexOf(' ', startPos); + string cmdText = endPos == -1 ? input.Substring(startPos) : input.Substring(startPos, endPos - startPos); + startPos = endPos + 1; + if (!_map.TryGetValue(cmdText, out group)) + break; + bestGroup = group; + } + + ImmutableArray cmds; + if (bestGroup != null) + { + lock (bestGroup) + cmds = bestGroup.ToImmutableArray(); + } + else + cmds = ImmutableArray.Create(); + return new CommandSearchResults(cmds, startPos); + } + } +} diff --git a/src/Discord.Net.Commands/CommandSearchResults.cs b/src/Discord.Net.Commands/CommandSearchResults.cs new file mode 100644 index 000000000..4e1cbe025 --- /dev/null +++ b/src/Discord.Net.Commands/CommandSearchResults.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Discord.Commands +{ + public struct CommandSearchResults + { + IReadOnlyList Commands { get; } + int ArgsPos { get; } + + public CommandSearchResults(IReadOnlyList commands, int argsPos) + { + Commands = commands; + ArgsPos = argsPos; + } + } +}