public ExprConst(LexExpr lex, CalcParam calc) : base(lex, calc) { switch (lex.DataType) { case DataType.Boolean: _moment = new Moment(DataType.Boolean, lex.Code); break; case DataType.Integer: _moment = new Moment(DataType.Integer, lex.Code); break; case DataType.Real: _moment = new Moment(DataType.Real, lex.Code); break; case DataType.Time: _moment = new Moment(DataType.Time, Lex.Code); break; case DataType.String: _moment = new Moment(DataType.String, calc.Strings[int.Parse(Lex.Code)]); break; } if (_moment == null) { _moment = new Moment(DataType.Boolean); } }
public ExprConst(string[] s, CalcParam calc) { _thread = calc.Project.ThreadCalc; switch (s[2].ToDataType()) { case DataType.Boolean: _moment = new Moment(DataType.Boolean, s[1]); break; case DataType.Integer: _moment = new Moment(DataType.Integer, s[1]); break; case DataType.Real: _moment = new Moment(DataType.Real, s[1]); break; case DataType.Time: _moment = new Moment(DataType.Time, s[1]); break; case DataType.String: _moment = new Moment(DataType.String, calc.Strings[int.Parse(s[1])]); break; } if (_moment == null) { _moment = new Moment(DataType.Boolean); } }
//Фабрика для создания Expr разного типа, на входе строка типа Type!Name(DataType,Par,Par,.....) public static Expr New(string s, CalcParam calc) { var lex = new LexExpr(s); switch (lex.Type) { case "const": return(new ExprConst(lex, calc)); case "signal": case "handsignal": return(new ExprSignal(lex, calc)); case "var": case "varuse": return(new ExprVar(lex, calc)); case "fun": return(new ExprFun(lex, calc)); case "calc": case "met": return(new ExprCalc(lex, calc)); case "prev": return(new ExprPrev(lex, calc)); case "grafic": return(new ExprGrafic(lex, calc)); case "op": return(new ExprOp(lex, calc)); } return(new ExprOp(lex, calc)); }
//Запуск экземпляра конкретной функции //funCode - код перегрузки функции, dataType - тип данных возвращаемого значения, calc - параметр, при расчете которого вызывается функция public static GeneralFunction Create(string funCode, DataType dataType, CalcParam calc) { var type = Type.GetType("Calculation." + Funs[funCode].Class); var fun = (GeneralFunction)Activator.CreateInstance(type); fun.CreateDelegate(Funs[funCode].Method); fun.CalcParam = calc; fun.DataType = dataType; return(fun); }
public ExprVar(string[] s, CalcParam calc) { IsUse = s[0] == "varuse"; CalcParam cp = calc; while (!cp.Vars.ContainsKey(s[1])) { cp = cp.Owner; } Code = s[1]; }
public ExprFun(LexExpr lex, CalcParam calc) : base(lex, calc) { string fname = lex.Code;//Имя делегата for (int k = 0; k < lex.Pars.Count; k++) { if (lex.Pars[k][0] != '$') { fname += lex.Pars[k].Substring(1); } } Fun = Thread.FunsDic[fname]; }
public ExprOp(LexExpr lex, CalcParam calc) : base(lex, calc) { var ss = Lex.Code.Split('_'); CodeFun = ss[0]; if (ss.Length > 1) { LinkAddress = int.Parse(ss[1]); } IsFilterIf = !new HashSet <string> { "void", "owner", "caller", "getelement" }.Contains(CodeFun) && !CodeFun.StartsWith("prev") && !CodeFun.StartsWith("signal") && !CodeFun.StartsWith("take"); }
public ExprSignal(LexExpr lex, CalcParam calc) : base(lex, calc) { var sou = calc.Signals[int.Parse(lex.Code)]; if (calc.Project.SignalsSources.ContainsKey(sou)) { _signal = calc.Project.SignalsSources[sou]; } if (lex.Type == "handsignal") { _handDefaultValue = calc.HandInputValue; } }
public ExprOp(string[] s, CalcParam calc) : base(s) { _calc = calc; var ss = s[1].Split('_'); Code = ss[0]; if (ss.Length > 1) { LinkAddress = int.Parse(ss[1]); } if (s.Length > 2) { DataType = s[2].ToDataType(); } IsFilterIf = !new HashSet <string> { "void", "owner", "caller", "getelement" }.Contains(Code) && !Code.StartsWith("prev") && !Code.StartsWith("signal") && !Code.StartsWith("take"); }
public ExprSignal(string[] s, CalcParam calc, bool isHand) { var sou = calc.Signals[int.Parse(s[1])]; if (calc.Project.SignalsSources.ContainsKey(sou)) { Signal = calc.Project.SignalsSources[sou]; if (Signal.SourceSignal == null) { ConstValue = Signal.ConstValue; } } _isHand = isHand; if (isHand) { ConstValue = calc.HandInputValue; } }
//Фабрика для создания Expr разного типа, на входе строка типа type!name(parmas) public static Expr New(string s, CalcParam calc) { var ss = s.Split(new[] { '!', '(', ',', ')' }, StringSplitOptions.RemoveEmptyEntries); switch (ss[0]) { case "const": return(new ExprConst(ss, calc)); case "signal": return(new ExprSignal(ss, calc, false)); case "handsignal": return(new ExprSignal(ss, calc, true)); case "var": case "varuse": return(new ExprVar(ss, calc)); case "fun": return(new ExprFun(ss, calc.Project.ThreadCalc)); case "calc": return(new ExprCalc(ss, false)); case "met": return(new ExprCalc(ss, true)); case "prev": return(new ExprPrev(ss)); case "grafic": return(new ExprGrafic(ss, calc)); case "op": return(new ExprOp(ss, calc)); } return(new ExprOp(ss, calc)); }
private void LoadParams(string fileName, string tablName) { using (var db = new DaoDb(Dir + fileName + ".accdb")) { var paramsId = new DicI <CalcParam>(); using (var rec = new DaoRec(db, tablName + "Params")) while (rec.Read()) { var cp = new CalcParam(this, rec, false); CalcParams.Add(cp.Code, cp); paramsId.Add(rec.GetInt("ParamId"), cp); } using (var rec = new DaoRec(db, tablName + "SubParams")) while (rec.Read()) { var cp = new CalcParam(this, rec, true); var owner = paramsId[rec.GetInt("ParamId")]; owner.SubParams.Add(cp.Code, cp); cp.Owner = owner; } } }
public ExprPrev(LexExpr lex, CalcParam calc) : base(lex, calc) { }
public ExprGrafic(string[] s, CalcParam calc) : base(s) { _calc = calc; Grafic = calc.Project.Grafics[s[1]]; }
public ExprGrafic(LexExpr lex, CalcParam calc) : base(lex, calc) { Grafic = calc.Project.Grafics[lex.Code]; }
protected Expr(LexExpr lex, CalcParam calc) { Lex = lex; CalcParam = calc; }
public CalcParamInstance(CalcParam param, List <IVal> inputs) { Param = param; }
//Чтение списка расчетных параметров private void ReadCalcParams() { CalcParamsCode.Clear(); CalcParamsId.Clear(); CalcSubParamsId.Clear(); Grafics.Clear(); AddEvent("Загрузка графиков"); using (var db = new DaoDb(File)) { try { const string stSql = "SELECT GraficsList.Code, GraficsList.Dimension, GraficsList.GraficType, GraficsValues.X1, GraficsValues.X2, GraficsValues.X3, GraficsValues.X4, GraficsValues.X5, GraficsValues.X6, GraficsValues.X7, GraficsValues.X8 " + "FROM GraficsList INNER JOIN GraficsValues ON GraficsList.GraficId = GraficsValues.GraficId " + "ORDER BY GraficsList.Code, GraficsValues.X8, GraficsValues.X7, GraficsValues.X6, GraficsValues.X5, GraficsValues.X4, GraficsValues.X3, GraficsValues.X2, GraficsValues.X1;"; using (var recg = new ReaderAdo(db, stSql)) { //Считывание графиков recg.Read(); while (!recg.EOF) { var gr = new Grafic(recg, ThreadCalc); Grafics.Add(gr.Code, gr); } } } catch (Exception ex) { AddError("Ошибка загрузки графика", ex); } Procent = 10; AddEvent("Загрузка параметров"); try { const string stSql = "SELECT * FROM CalcParams WHERE (TaskOn = True) AND (CalcOn = True)"; using (var rec = new ReaderAdo(db, stSql)) while (rec.Read()) { var calc = new CalcParam(this, rec, false); calc.FullCode = calc.Code; CalcParamsId.Add(calc.Id, calc); CalcParamsCode.Add(calc.Code, calc); if (IsError) { return; } } } catch (Exception ex) { AddError("Список расчетных параметров загружен с ошибками, необходима повторная компиляция расчета", ex); } Procent = 40; AddEvent("Загрузка подпараметров"); try { const string stSql = "SELECT CalcSubParams.* FROM CalcParams INNER JOIN CalcSubParams ON CalcParams.CalcParamId = CalcSubParams.OwnerId" + " WHERE (CalcParams.TaskOn=True) AND (CalcParams.CalcOn=True) AND (CalcSubParams.CalcOn=True)"; using (var recp = new ReaderAdo(db, stSql)) while (recp.Read()) { var calc = new CalcParam(this, recp, true); CalcSubParamsId.Add(calc.Id, calc); calc.Owner = CalcParamsId[recp.GetInt("OwnerId")]; calc.Owner.Methods.Add(calc.Code, calc); calc.FullCode = calc.Owner.FullCode + "." + calc.Code; if (IsError) { return; } } } catch (Exception ex) { AddError("Список расчетных параметров загружен с ошибками, необходима повторная компиляция расчета", ex); } Procent = 60; } AddEvent("Загрузка справочных таблиц"); Tabls.Clear(); using (var db = new DaoDb(File).ConnectDao()) foreach (TableDef t in db.Database.TableDefs) { if (t.Name.StartsWith("Tabl_")) { var tabl = new Tabl(int.Parse(t.Name.Substring(5))); Tabls.Add(tabl.Num, tabl); tabl.FieldsCount = 0; foreach (Field f in t.Fields) { if (f.Name.StartsWith("Val_")) { int fnum = int.Parse(f.Name.Substring(4)); if (fnum >= tabl.FieldsCount) { tabl.FieldsCount = fnum + 1; } } } TableDef st = db.Database.TableDefs["Sub" + t.Name]; tabl.SubFieldsCount = 0; foreach (Field f in st.Fields) { if (f.Name.StartsWith("SubVal_")) { int fnum = int.Parse(f.Name.Substring(7)); if (fnum >= tabl.SubFieldsCount) { tabl.SubFieldsCount = fnum + 1; } } } } } if (Tabls.Count > 0) { using (var db = new DaoDb(File)) foreach (var t in Tabls.Values) { using (var rect = new ReaderAdo(db, "SELECT * FROM Tabl_" + t.Num)) while (rect.Read()) { new TablParam().ParamFromRec(t, rect); } using (var rect = new ReaderAdo(db, "SELECT * FROM SubTabl_" + t.Num)) while (rect.Read()) { new TablParam().SubParamFromRec(t, rect); } } } Procent = 75; AddEvent("Разбор выражений"); try { foreach (var cp in CalcParamsId.Values) { if (!Start(cp.Parse)) { break; } } } catch (Exception ex) { ThreadCalc.AddError("Список расчетных параметров загружен с ошибками, необходима повторная компиляция расчета", ex); } }
public CalcKeeper(CalcParam param) { Param = param; }
//calc - CalcParam с формулой для расчета, inputs - список входных значений //owner - владелец, caller - параметр, из которого вызывается public CalcParamRun(CalcParam calc, CalcValue[] inputs, CalcParamRun owner, CalcParamRun caller) { CalcParam = calc; Owner = owner; Caller = caller; if (inputs == null || inputs.Length == 0) { Owner.Methods.Add(calc.Code, this); if (calc.IsNotObject) { calc.RunParam = this; } } StackDepth = caller == null ? 1 : caller.StackDepth + 1; if (StackDepth > 500) { CalcValue = new CalcValue(new SingleValue(new Moment(DataType.Value, new ErrorCalc("Переполнение стека", CalcParam.FullCode)))); return; } foreach (var k in calc.Vars.Keys) { Vars.Add(k, new VarRun(calc.Vars[k])); } if (inputs != null) { for (int i = 0; i < inputs.Length; i++) { VarRun v = Vars[calc.Inputs[i]]; v.CalcValue = inputs[i]; Inputs.Add(v); } } ThreadCalc = CalcParam.Project.ThreadCalc; //Сразу производится расчет Calculate(); //Добавление ошибок расчета в проект if (CalcParam.Inputs.Count == 0) { var errors = CalcParam.Project.CalcErrors; if (CalcValue.Type != CalcValueType.Single) { if (CalcValue.Error != null) { errors.Add(CalcValue.Error); } } else { var sv = CalcValue.SingleValue; if (sv.Moment != null && sv.Moment.Error != null) { errors.Add(sv.Moment.Error); } if (sv.Moments != null) { foreach (var m in sv.Moments) { if (m.Error != null) { errors.Add(m.Error); break; } } } if (sv.Segments != null) { foreach (var seg in sv.Segments) { if (seg.Error != null) { errors.Add(seg.Error); break; } } } } } }
protected override CalcValue GetValue() { switch (CodeFun) { case "void": return(new CalcValue()); case "owner": var cv = CalcRun.Owner.CalcValue; if (cv.ParentParam == null) { cv = cv.LinkClone(CalcRun.Owner); } return(cv); case "caller": return(new CalcValue { ParentParam = CalcRun.Caller }); case "getelement": if (Inputs[1].Type != CalcValueType.Single || Inputs[1].SingleValue.Type != SingleType.Moment) { return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Индекс массива должен быть отдельным значением", CalcParam.Code))))); } Moment m = Inputs[1].SingleValue.Moment; if (m.DataType.LessOrEquals(DataType.Integer)) { if (Inputs[0].IntArray == null || !Inputs[0].IntArray.ContainsKey(m.Integer)) { return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Несуществующий индекс массива (" + m.Integer + ")", CalcParam.Code))))); } return(Inputs[0].IntArray[m.Integer].CalcValue); } if (Inputs[0].StringArray == null || !Inputs[0].StringArray.ContainsKey(m.String)) { return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Несуществующий индекс массива (" + m.String + ")", CalcParam.Code))))); } return(Inputs[0].StringArray[m.String].CalcValue); case "signal": return(Inputs[0].Signal.Object.Signals[Inputs[1].SingleValue.LastMoment.String].CalcValue); case "signalbool": case "signalint": case "signalreal": case "signalstring": string c = Inputs[0].SingleValue.LastMoment.String ?? ""; CalcSignal sig = null; if (CalcParam.Project.SignalsSources.ContainsKey(c)) { sig = CalcParam.Project.SignalsSources[c]; } if (CalcParam.Project.Objects.ContainsKey(c)) { sig = CalcParam.Project.Objects[c].DefaultSignal; } if (sig == null || !sig.DataType.LessOrEquals(CodeFun.Substring(6).ToDataType())) { return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Строка задает несуществующий сигнал или сигнал недопустимого типа (" + c + ")", CalcParam.Code))))); } return(sig.CalcValue); case "takecode": case "takename": case "takeunits": case "taketask": case "takecomment": case "takecodesignal": case "takenamesignal": CalcParam cp = null; if (Inputs.Length == 0) { cp = CalcParam; } else if (Inputs[0].ParentParam != null) { cp = Inputs[0].ParentParam.CalcParam; } else if (Inputs[0].Signal != null) { var si = Inputs[0].Signal; return(new CalcValue(new SingleValue(new Moment(CalcRun.ThreadCalc.PeriodBegin, CodeFun == "takecode" ? si.CodeObject : CodeFun == "takecodesignal" ? si.CodeSignal : CodeFun == "takename" ? si.NameObject : CodeFun == "takenamesignal" ? si.NameSignal : si.Units)))); } if (cp != null) { return(new CalcValue(new SingleValue(new Moment(CalcRun.ThreadCalc.PeriodBegin, CodeFun == "takecode" ? cp.Code : CodeFun == "takename" ? cp.Name : CodeFun == "taketask" ? cp.Task : CodeFun == "takecomment" ? cp.Comment : cp.Units)))); } return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Параметр функции получения характеристики не задает расчетный параметр или сигнал", CalcParam.Code))))); case "prevabs": case "prevmom": case "prev": case "prevperiod": case "prevhour": case "prevhourperiod": case "prevday": case "prevdayperiod": return(new CalcValue(CalcPrev(CodeFun, Inputs))); } return(null); }
//Вычисление значения функций типа 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); }