Example #1
0
        /// <summary>
        /// Пытается созадть готовую к исполнению команду. Если команда не может быть исполнена на данный момент, то возвращает false.
        /// </summary>
        /// <param name="command_header">Заголовок команды.</param>
        /// <param name="new_command">Созданная команда.</param>
        /// <returns>Удалось ли создать готовую к исполнению команду.</returns>
        private bool TryCreateCommand(CommandHeader command_header, out Command new_command)
        {
            new_command = null;

            // Если условия ещё не готовы, то возвращаем null.
            if (!CheckCommandCodition(command_header, out List <DataCell> condition_data))
            {
                return(false);
            }

            // Если нет ни одного истинного условия, то возвращаем null.
            if (condition_data.Any(x => x.HasValue.HasValue && x.HasValue.Value && !(bool)x.Data))
            {
                return(false);
            }

            // Подготавливае места для ячеек с выходными данными.
            var count      = command_header.InputDataHeaders.Count;
            var input_data = new DataCell[count];

            new_command = new Command()
            {
                Header = new InvokeHeader()
                {
                    CallStack = command_header.CallStack
                },
                InputData     = input_data.ToList(),
                OutputData    = GetOutputData(command_header.OutputDataHeader),
                ConditionData = condition_data
            };

            var all_ready = true;

            switch (command_header.FunctionHeader.Condition)
            {
            case InputParamCondition.All:
                // Получаем или подписываемся на получение входных параметров.
                for (int i = 0; i < command_header.InputDataHeaders.Count; i++)
                {
                    var result = GetDataCell(command_header.InputDataHeaders[i]);
                    new_command.InputData[i] = result;

                    if (result.HasValue == null)
                    {
                        all_ready = false;
                    }
                }
                break;

            case InputParamCondition.Any:
                var any = false;
                // Получаем или подписываемся на получение входных параметров.
                for (int i = 0; i < command_header.InputDataHeaders.Count; i++)
                {
                    var result = GetDataCell(command_header.InputDataHeaders[i]);
                    new_command.InputData[i] = result;

                    if (result.HasValue != null && result.HasValue.Value)
                    {
                        any = true;
                    }
                }

                if (!any)
                {
                    all_ready = false;
                }
                break;

            default:
                throw new Exception($"CreateNewCommand Неизвестный тип: {command_header.FunctionHeader.Condition}");
            }

            if (!all_ready)
            {
                AddCommandToPreparing(new_command);
            }
            _dataCellRepository.Add(new_command.InputData.Where(x => x.HasValue == null), false);

            // Получаем или подписываемся на получение функций.
            var function = _functionRepository.Get(command_header.FunctionHeader.Token).FirstOrDefault();

            if (function == null)
            {
                if (all_ready)
                {
                    all_ready = false;
                    AddCommandToPreparing(new_command);
                }
                //_functionRepository.Subscribe(function_header, OnFunctionReady);
                // TODO: нужно отправлять запросы на другие узлы для получения функции.
            }
            else
            {
                new_command.Function = function;
            }

            return(all_ready);
        }