public static int ExecuteScalar(ScalarDelegate scalar, string[] args, ref int errorNumber, Func <MethodBase> method) { int successful = 0; try { errorNumber = scalar(args, ref errorNumber); successful = 1; } catch (Exception ex) { // log.Error("Error while executing", ex); //TODO: Code to log error. } return(successful); }
//Вычисление значения функций типа scalar и list public CalcValue GeneralFunction(CalcValue[] par, DataType dt, CalcParamRun calc, ScalarDelegate scalar, ListDelegate fun) { bool isScalar = scalar != null; int n = par.Count(); _calc = calc.CalcParam; Begin = calc.ThreadCalc.PeriodBegin; End = calc.ThreadCalc.PeriodEnd; _interpol = _calc.Interpolation; var sv = new SingleValue[n]; int ki = 0, ks = 0; for (int i = 0; i < n; i++) { var cvt = par[i].Type; if (ki == 0 && cvt == CalcValueType.IntArray) { ki = i; } if (ks == 0 && cvt == CalcValueType.StringArray) { ks = i; } if (cvt != CalcValueType.IntArray && cvt != CalcValueType.StringArray) { sv[i] = par[i].SingleValue; } } if (ki == 0 && ks == 0)//Нет массивов { if (isScalar) { return(new CalcValue(ScalarFunction(sv, dt, scalar))); } var ss = new SingleValue(); foreach (var s in sv) { ss.Error |= s.Error; } fun(sv, ss); if (ss.Type != SingleType.Segments && ss.Moment == null && ss.Moments == null) { ss.Moments = new List <Moment>(); } if (ss.Type == SingleType.Segments && ss.Segments == null) { ss.Segments = new List <Segment>(); } return(new CalcValue(ss)); } var cv = new CalcValue[n]; if (ki > 0)//Массивы с целыми индексами { var resi = new CalcValue(new SortedDictionary <int, VarRun>()); foreach (var key in par[ki].IntArray.Keys) { bool e = true; for (int i = 0; i < n; i++) { var p = par[i]; if (p.Type == CalcValueType.StringArray || (p.Type == CalcValueType.IntArray && !p.IntArray.ContainsKey(key))) { e = false; } else if (p.Type == CalcValueType.IntArray) { cv[i] = p.IntArray[key].CalcValue; } else { cv[i] = p; } } if (e) { var c = GeneralFunction(cv, dt, calc, scalar, fun); resi.Error |= c.Error; resi.IntArray.Add(key, new VarRun(c)); } } return(resi); } //Массивы со строковыми индексами var ress = new CalcValue(new SortedDictionary <int, VarRun>()); foreach (var key in par[ki].StringArray.Keys) { bool e = true; for (int i = 0; i < n; i++) { var p = par[i]; if (p.Type == CalcValueType.IntArray || (p.Type == CalcValueType.StringArray && !p.StringArray.ContainsKey(key))) { e = false; } else if (p.Type == CalcValueType.StringArray) { cv[i] = p.StringArray[key].CalcValue; } else { cv[i] = p; } } if (e) { var c = GeneralFunction(cv, dt, calc, scalar, fun); ress.Error |= c.Error; ress.StringArray.Add(key, new VarRun(c)); } } return(ress); }
//Вычисления значения скалярной функции, параметры: par - списки Moment, dt - тип данных результата, public SingleValue ScalarFunction(SingleValue[] par, DataType dt, ScalarDelegate scalar, ComplicateDelegate comp = null) { ErrorCalc error = null; _errorScalar = null; int n = par.Length; var pos = new int[n]; //Текущий обрабатываемый индекс для каждого списка var islist = new bool[n]; //Значение является списком var spar = new Moment[n]; //Параметры для вызова скалярного делегата var list = new List <Moment> [n]; //Параметры, обрабатываемые как списки (а не как константы) bool hasList = false; //Среди параметров есть хоть один список for (int i = 0; i < n; ++i) { pos[i] = -1; if ((par[i].Moments == null || par[i].Moments.Count == 0) && par[i].Moment == null && !(comp != null && (comp.Method.Name == "Compunion" || comp.Method.Name == "Compendifp"))) //Пустой список { return(new SingleValue(new List <Moment>())); } if (comp == null) { hasList |= islist[i] = (par[i].Type == SingleType.List); if (!islist[i]) { spar[i] = par[i].Moment; } else { list[i] = par[i].Moments; } } else { hasList = islist[i] = true; if (par[i].Moments != null) { list[i] = par[i].Moments; } else { list[i] = new List <Moment>(); if (par[i].Moment != null) { list[i].Add(par[i].Moment); } } } //hasList |= par[i].Type == SingleType.List; //if (comp != null && par[i].Moment != null) // list[i] = new List<Moment> {par[i].Moment}; //else list[i] = par[i].Moments; //pos[i] = -1; //if (par[i].Type == SingleType.Moment && comp == null) // spar[i] = par[i].Moment; } if (!hasList) //Одно значение { DateTime t = Different.MaxDate; foreach (var p in par) { if (p.Moment.Time != Different.MinDate && p.Moment.Time < t) { t = p.Moment.Time; } } if (t == Different.MaxDate) { t = Begin; } var mv = new Moment(dt, t, MaxErr(spar), MaxNd(spar)); scalar(spar, mv); return(new SingleValue(mv) { Error = mv.Error }); } //Список значений var rlist = new List <Moment>();//Результаты var d = Different.MaxDate; bool e = true; var parnum = new HashSet <int>(); //Номера параметров с точками в рассматриваемое время while (e) { e = false; DateTime ctime = d; for (int i = 0; i < n; ++i) { if (islist[i] && pos[i] + 1 < list[i].Count) { e = true; if (ctime > list[i][pos[i] + 1].Time) { ctime = list[i][pos[i] + 1].Time; } } } if (e) { parnum.Clear(); for (int i = n - 1; i >= 0; --i) { if (islist[i]) { if (pos[i] + 1 < list[i].Count && ctime == list[i][pos[i] + 1].Time) { pos[i]++; parnum.Add(i); } spar[i] = Interpolation(_interpol, list[i], pos[i], ctime); } } var m = new Moment(dt, ctime, MaxErr(spar), MaxNd(spar)); if (comp == null) { scalar(spar, m); if (scalar.Method.Name != "endif") { error |= MaxErr(spar); } error |= _errorScalar; rlist.Add(m); } else if (comp(spar, m, parnum)) { rlist.Add(m); } } } return(new SingleValue(rlist) { Error = error }); }
//Инициализирует конкретную функцию расчета protected override void CreateDelegate(string funName) { _scalarCalculate = (ScalarDelegate)Delegate.CreateDelegate(typeof(ScalarDelegate), this, funName); MomCalculate = MomFun; }
//Создание экземпляра делегата функции protected override void CreateDelegateInstance(BaseFunctions funs, MethodInfo met) { Fun = (ScalarDelegate)Delegate.CreateDelegate(typeof(ScalarDelegate), funs, met); }