/// <summary> /// Создает команду из заголовка. Если данных недостаточно, то возвращает <code>null</code>. /// </summary> /// <param name="command_header"></param> /// <param name="not_ready_data"></param> /// <returns></returns> public Command CreateCommand(CommandHeader command_header, out Tuple <FunctionHeader, List <DataCellHeader> > not_ready_data) { not_ready_data = null; var input_data = new List <DataCell>(); var empty_input_data = new List <DataCellHeader>(); foreach (var data_cell_header in command_header.InputDataHeaders) { var data = _dataCellRepository.Get(new[] { data_cell_header }).FirstOrDefault(); if (data != null) { input_data.Add(data); } else { empty_input_data.Add(data_cell_header); } } var output_data = _dataCellRepository.Get(new[] { command_header.OutputDataHeader }).FirstOrDefault(); if (output_data == null) { output_data = new DataCell() { Header = command_header.OutputDataHeader, //HasValue = false, HasValue = null, Data = null }; } var function = _functionRepository.Get(new[] { command_header.FunctionHeader }).FirstOrDefault(); if (empty_input_data.Any() || function == null) { not_ready_data = new Tuple <FunctionHeader, List <DataCellHeader> >(function == null ? command_header.FunctionHeader : null, empty_input_data); return(null); } return(new Command() { Header = new InvokeHeader() { CallStack = command_header.CallStack }, Function = function, InputData = input_data, OutputData = output_data }); }
public virtual void Execute(Function function, IEnumerable <DataCell> input_data, DataCell output, CommandContext command_context = null) { var func = _functionRepository.Get <CSharpFunction>(new List <FunctionHeader>() { (FunctionHeader)function.Header }).FirstOrDefault(); if (func == null) { throw new System.NotImplementedException("Нужно попытаться получить функцию."); } var full_name = ((CSharpFunctionHeader)function.Header).Namespace; // var types = func.Assembly.GetTypes(); var type = func.Assembly.GetType($"{full_name}.{func.ClassName}"); var method = type.GetMethod(func.FuncName); output.Data = method.Invoke(null, input_data.Select(x => x.Data).ToArray()); output.HasValue = true; }
/// <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); }
public virtual IEnumerable <Function> GetFunctions(IEnumerable <FunctionHeader> functions) { return(_functionRepository.Get(functions)); }