コード例 #1
0
        private void ParserThreadCallback()
        {
            while (!_tokenSource.Token.IsCancellationRequested)
            {
                //Check if the MRE has been set
                if (!_mre.WaitOne(100))
                {
                    continue;
                }

                if (!_queue.TryDequeue(out QueueData data))
                {
                    _mre.Reset();
                    continue;
                }

                //The vertical bar is a pipe character. inputA | inputB = run command B with the output of command A
                string[] inputs = data.Input.Split('|');

                if (inputs.Length > 1)
                {
                    //If we have a piped command, send it off to a new thread to be handled,
                    //As each command needs to be handled in order
                    Thread pipeThread = new Thread(() => PipeThreadCallback(inputs, data.Callback, data.Context));
                    pipeThread.Start();
                    _mre.Set();
                    continue;
                }

                string input = data.Input; //We don't lower the data because case sensitivity is an option for command matching

                CommandMetadata metadata;
                lock (_lock)
                {
                    //Lock the metadata collection, and grab the first metadata that has a matching executor
                    List <CommandMetadata> metadatas = _metadata.Where(m => m.GetFirstOrDefaultExecutorData(input) != null).ToList();
                    metadata = metadatas.FirstOrDefault();
                }

                if (metadata == null)
                {
                    data.Callback?.Invoke(InputResult.Unhandled, null);

                    //No command matches, so ignore this input
                    _mre.Set();
                    continue;
                }

                CommandExecutorData exeData = metadata.GetFirstOrDefaultExecutorData(input);

                RegexString trigger = exeData.ExecutorAttribute.CommandMatcher;
                input = trigger.RemoveMatchedString(input).TrimStart();

                AbstractParser parser = _registry.GetParser(_registry, input, null, metadata, exeData, data.Context, data.Callback);

                try
                {
                    parser.Start();
                }
                finally
                {
                    //Our job is done, so prepare for the next input
                    _mre.Set();
                }
            }

            _mre.Dispose();
        }