diff --git a/.vscode/launch.json b/.vscode/launch.json index be37e2d1bdf7fef954f0e29a3c64ca397f7415a1..b627ca869d60e1b451d619ebfe96d0d68513cff5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { "name": "Launch Program", "type": "node", @@ -14,7 +15,7 @@ "${workspaceRoot}/build/**/*.js" ], "cwd": "${workspaceRoot}", - // "preLaunchTask": "buildspec" + "preLaunchTask": "buildspec" } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8379e3ff2087b7446cabec75434a16916aae6722..0f4734d17fd2ea08611521470cb5f04c24acd7f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "jalhyd", - "version": "1.0.2", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts index 2baf17136e0af0f3d14d27c2a7a5d47d49aa5395..e3a0c3fa63e86f26d9002005bafe80c062d401c8 100644 --- a/spec/mock_jasmine.ts +++ b/spec/mock_jasmine.ts @@ -161,8 +161,7 @@ class Expect { if (exception.message !== expected.message) { console.error(`Function throws '${exception.message}' but '${expected.message}' was expected`); } - } - else if (exception.message) { + } else if (exception.message) { console.error(`Function throws '${exception.message}' but no message was expected`); } } diff --git a/spec/nubtest.ts b/spec/nubtest.ts index 5d8c6bedcf7da95be4270fea7f9768ed8ba7ff9a..710e3526b5b170efe7c10bc27bbe3c7ebe54f61f 100644 --- a/spec/nubtest.ts +++ b/spec/nubtest.ts @@ -1,7 +1,7 @@ -import { Result } from "../src/util/result"; +import { ParamCalculability, ParamDefinition, ParamDomainValue } from "../src"; import { Nub } from "../src/nub"; import { ParamsEquation } from "../src/param/params-equation"; -import { ParamDefinition, ParamDomainValue, ParamCalculability } from "../src"; +import { Result } from "../src/util/result"; export class NubTestParams extends ParamsEquation { private _A: ParamDefinition; @@ -32,11 +32,17 @@ export class NubTestParams extends ParamsEquation { } } +// tslint:disable-next-line:max-classes-per-file export class NubTest extends Nub { constructor(prms: NubTestParams, dbg: boolean = false) { super(prms, dbg); } + public Equation(): Result { + // C = A+B + return new Result(this.prms.A.v + this.prms.B.v); + } + protected setParametersCalculability() { this.getParameter("A").calculability = ParamCalculability.DICHO; this.getParameter("B").calculability = ParamCalculability.DICHO; @@ -47,10 +53,6 @@ export class NubTest extends Nub { return this._prms as NubTestParams; } - Equation(): Result { - // C = A+B - return new Result(this.prms.A.v + this.prms.B.v); - } } export let nub = new NubTest(new NubTestParams()); diff --git a/spec/value_ref/value_ref.spec.ts b/spec/value_ref/value_ref.spec.ts index 82ed531ea7af2861f4a8d7cb79e7880a30f29053..b442a245774cff8b8651132d141c950efacb9f25 100644 --- a/spec/value_ref/value_ref.spec.ts +++ b/spec/value_ref/value_ref.spec.ts @@ -6,10 +6,10 @@ */ // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine"; +import { Result } from "../../src"; +import { ParamValueMode } from "../../src/param/param-value-mode"; import { NubTest, NubTestParams } from "../nubtest"; import { precDigits } from "../test_config"; -import { ParamValueMode } from "../../src/param/param-value-mode"; -import { Result } from "../../src"; let nub1: NubTest; let nub2: NubTest; @@ -181,7 +181,7 @@ describe("référence d'un paramètre à un autre : ", () => { it('test 3', () => { // cas de figure : // nub2.A est lié à nub1.A (valeur variée) - // lecture de nub2.A + // lecture de nub2.A createEnv(); diff --git a/spec/value_ref/value_ref_variable.spec.ts b/spec/value_ref/value_ref_variable.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..21fc66aad4cbbbef32bf9c65011dad53ee6530b6 --- /dev/null +++ b/spec/value_ref/value_ref_variable.spec.ts @@ -0,0 +1,54 @@ +import { ParamValueMode } from "../../src"; +import { ConduiteDistrib, ConduiteDistribParams } from "../../src/cond_distri"; +import { Result } from "../../src/util/result"; + +/** + * IMPORTANT ! + * Décommenter temporairement la ligne suivante (import { } from "./mock_jasmine") + * Pour exécuter ce code dans le débugger. + * Faire de même avec le fichier test_func.ts + */ +// import { describe, expect, it, xdescribe, xit } from "../mock_jasmine"; + +let nub1: ConduiteDistrib; +let nub2: ConduiteDistrib; +let prm1: ConduiteDistribParams; +let prm2: ConduiteDistribParams; + +/** + * crée l'environnement de test. + * répété à chaque test car il manque un mock de beforeEach + */ +function createEnv() { + // Nub maître + nub1 = new ConduiteDistrib(new ConduiteDistribParams(3, 1.2, 0.6, 100, 0.000001)); + prm1 = nub1.parameters as ConduiteDistribParams; + + // Nub esclave + nub2 = new ConduiteDistrib(new ConduiteDistribParams(3, 1.2, 0.6, 100, 0.000001)); + prm2 = nub2.parameters as ConduiteDistribParams; +} + +describe("Référence d'un paramètre à un paramètre varié : ", () => { + it("ConduiteDistri Q varie sur nub1, nub2.Q => nub1.Q, calcul et comparaison de J pour les deux", () => { + // cas de figure : + // nub2.Q est lié au résultat J de nub1 + // lecture de nub2.Q + + createEnv(); + + prm1.Q.paramValues.valueMode = ParamValueMode.MINMAX; + prm1.Q.paramValues.min = 1.5; + prm1.Q.paramValues.max = 6; + prm1.Q.paramValues.step = 0.5; + const res1: Result = nub1.CalcSerie(0.001, 0.6, "J"); + + prm2.Q.defineReference(nub1, "Q"); + const res2 = nub2.CalcSerie(0.001, 0.6, "J"); + + for (let i = 0; i < res1.resultElements.length; i++) { + expect(res1.resultElements[i].vCalc).toEqual(res2.resultElements[i].vCalc); + } + + }); +}); diff --git a/spec/value_ref/value_ref_variable_result.spec.ts b/spec/value_ref/value_ref_variable_result.spec.ts index 9eff1a2bbaccef2f7902459bf49b06a320188cff..0a3ba248e0eed0c6a4c87b4bf009e727b07b1e87 100644 --- a/spec/value_ref/value_ref_variable_result.spec.ts +++ b/spec/value_ref/value_ref_variable_result.spec.ts @@ -1,6 +1,6 @@ -import { ConduiteDistrib } from "../../src/cond_distri"; -import { ConduiteDistribParams } from "../../src/cond_distri"; import { ParamValueMode } from "../../src"; +import { ConduiteDistrib, ConduiteDistribParams } from "../../src/cond_distri"; +import { Result } from "../../src/util/result"; /** * IMPORTANT ! @@ -29,8 +29,25 @@ function createEnv() { prm2 = nub2.parameters as ConduiteDistribParams; } -describe("référence d'un paramètre à un résultat multivalué : ", () => { - it("test 1", () => { +describe("référence d'un paramètre à un résultat : ", () => { + it("ConduiteDistri Q fixe => Calc(J) => Importe(J) => Calc(Q)", () => { + // cas de figure : + // nub2.Q est lié au résultat J de nub1 + // lecture de nub2.Q + + createEnv(); + + prm1.Q.v = 2; + prm1.J.paramValues.valueMode = ParamValueMode.CALCUL; + const res1: Result = nub1.CalcSerie(0.001, 0.6, "J"); + + prm2.J.defineReference(nub1, "J"); + const res2 = nub2.CalcSerie(0.001, 0.6, "Q"); + + expect(res2.vCalc).toBeCloseTo(prm1.Q.v, 3); + }); + + it("ConduiteDistri Q varie => Calc(J) => Importe(J) => Calc(Q)", () => { // cas de figure : // nub2.Q est lié au résultat J de nub1 // lecture de nub2.Q @@ -41,28 +58,18 @@ describe("référence d'un paramètre à un résultat multivalué : ", () => { prm1.Q.paramValues.min = 1.5; prm1.Q.paramValues.max = 6; prm1.Q.paramValues.step = 0.5; - prm2.Q.defineReference(nub1, "J."); + prm1.J.paramValues.valueMode = ParamValueMode.CALCUL; + const res1: Result = nub1.CalcSerie(0.001, 0.6, "J"); - const expectedJ: number[] = [0.024202971271651448, 0.04004160474685753, 0.059170330781816, 0.08140876712328136, 0.10661739314398751, 0.1346833675705545, 0.16551253143900968, 0.19902447617522237, 0.23514929908544743, 0.273825361776767]; + prm2.J.defineReference(nub1, "J"); + const res2 = nub2.CalcSerie(0.001, 0.6, "Q"); - const res = nub1.CalcSerie(0.001, 0.6, "J"); - let i = 0; - for (const re of res.resultElements) + let QREF = prm1.Q.paramValues.min = 1.5; + for (const re of res2.resultElements) { // console.log(re.vCalc); - expect(re.vCalc).toEqual(expectedJ[i++]); - - i = 0; - for (const v of res.valuesIterator) - expect(v).toEqual(expectedJ[i++]); - expect(i).toEqual(expectedJ.length); - - // i = 0; - // for (const v of prm1.J.valuesIterator) - // expect(v).toEqual(expectedJ[i++]); // échoue car le valueMode de J (SINGLE) n'est pas modifié par CalcSerie() + expect(re.vCalc).toEqual(QREF); + QREF += prm1.Q.paramValues.step; + } - i = 0; - for (const v of prm2.Q.valuesIterator) - expect(v).toEqual(expectedJ[i++]); - expect(i).toEqual(expectedJ.length); }); }); diff --git a/src/nub.ts b/src/nub.ts index 68ae8e3cadee30d7f285008c7a2d449965956e98..6c869ca68c506214d47c3f20f6c1d8ea0555518b 100644 --- a/src/nub.ts +++ b/src/nub.ts @@ -1,24 +1,25 @@ +import { ParamDefinition } from "."; import { Debug } from "./base"; -import { Dichotomie } from "./dichotomie"; import { ComputeNode } from "./compute-node"; -import { Result } from "./util/result"; -import { ParamValues } from "./param/param-values"; +import { Dichotomie } from "./dichotomie"; +import { NamedIterableValues, NumberIterator } from "./param/param-value-iterator"; import { ParamValueMode } from "./param/param-value-mode"; -import { ParamDefinition } from "."; +import { ParamValues } from "./param/param-values"; +import { Result } from "./util/result"; import { IReferencedNub } from "./value_ref/object_ref"; -import { NamedIterableValues, NumberIterator } from "./param/param-value-iterator"; /** * Classe abstraite de Noeud de calcul : classe de base pour tous les calculs */ export abstract class Nub extends ComputeNode implements IReferencedNub { - private _dichoStartIntervalMaxSteps: number = 100; /** * résultat de Calc()/CalcSerie() */ protected _result: Result; + private _dichoStartIntervalMaxSteps: number = 100; + /* * paramétrage de la dichotomie */ @@ -75,9 +76,9 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { * @param sDonnee éventuel symbole du paramètre à calculer */ public CalcSerie(rPrec: number = 0.001, rInit?: number, sDonnee?: string): Result { - let variatedParam: ParamDefinition; let computedParam: ParamDefinition; - let prmValue: ParamValues; // instance de ParamValues utilisée pour le paramètre varié (qui peut être un paramètre référencé (importé)) + // instance de ParamValues utilisée pour le paramètre varié (qui peut être un paramètre référencé (importé)) + let variatedPrmValues: ParamValues; for (const p of this.parameterIterator) { switch (p.valueMode) { @@ -86,76 +87,82 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { case ParamValueMode.LISTE: case ParamValueMode.MINMAX: - if (variatedParam == undefined) { - variatedParam = p; - prmValue = p.paramValues; + if (variatedPrmValues === undefined) { + variatedPrmValues = p.paramValues; + } else { + // tslint:disable-next-line:max-line-length + throw new Error(`CalcSerie() : il y plusieurs paramètres à varier : ${p.symbol}`); } - else - throw new Error(`CalcSerie() : il y plusieurs paramètres à varier (au moins ${variatedParam.symbol} et ${p.symbol})`); break; case ParamValueMode.CALCUL: - if (sDonnee == undefined) { - if (computedParam == undefined) + if (sDonnee === undefined) { + if (computedParam === undefined) { computedParam = p; - else + } else { + // tslint:disable-next-line:max-line-length throw new Error(`CalcSerie() : il y plusieurs paramètres à calculer (au moins ${computedParam.symbol} et ${p.symbol})`); + } } break; case ParamValueMode.LINK: - if (p.referencedParamValues !== undefined) + if (p.referencedParamValues !== undefined) { switch (p.referencedParamValues.valueMode) { case ParamValueMode.SINGLE: break; case ParamValueMode.LISTE: case ParamValueMode.MINMAX: - if (variatedParam == undefined) { - variatedParam = p; - prmValue = p.referencedParamValues; - } - else - throw new Error(`CalcSerie() : il y plusieurs paramètres à varier (au moins ${variatedParam.symbol} et ${p.symbol})`); + variatedPrmValues = this.setVariatedPrmValues( + p.referencedParamValues, variatedPrmValues, p.symbol + ); break; case ParamValueMode.CALCUL: - if (sDonnee == undefined) { - if (computedParam == undefined) - computedParam = p; - else - throw new Error(`CalcSerie() : il y plusieurs paramètres à calculer (au moins ${computedParam.symbol} et ${p.symbol})`); + // Le paramètre lié est un résultat de calcul + if (p.referencedResult.nbResultElements > 1) { + variatedPrmValues = this.setVariatedPrmValues( + p.referencedParamValues, variatedPrmValues, p.symbol + ); } break; default: + // tslint:disable-next-line:max-line-length throw new Error(`CalcSerie() : valeur référencée de ParamValueMode ${ParamValueMode[p.referencedParamValues.valueMode]} non prise en charge`); } + } break; default: + // tslint:disable-next-line:max-line-length throw new Error(`CalcSerie() : valeur de ParamValueMode ${ParamValueMode[p.valueMode]} non prise en charge`); } } - if (sDonnee) - var computedSymbol: string = sDonnee; - else { - if (computedParam == undefined) + let computedSymbol: string; + if (sDonnee) { + computedSymbol = sDonnee; + } else { + if (computedParam === undefined) { throw new Error(`CalcSerie() : aucun paramètre à calculer`); + } computedSymbol = computedParam.symbol; } - if (rInit === undefined) + if (rInit === undefined) { rInit = computedParam.v; + } - if (variatedParam == undefined) + if (variatedPrmValues === undefined) { this._result = this.Calc(computedSymbol, rInit, rPrec); // résultat dans this._result - else { + } else { const res = new Result(); - prmValue.initIterator(); - while (prmValue.hasNext) { - prmValue.next; + variatedPrmValues.initIterator(); + while (variatedPrmValues.hasNext) { + // tslint:disable-next-line:no-unused-expression + variatedPrmValues.next; this.Calc(computedSymbol, rInit, rPrec); // résultat dans this._result if (this._result.ok) { res.addResultElement(this._result.resultElement); @@ -171,19 +178,6 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { return this._result; } - /** - * Résoud l'équation par une méthode numérique - * @param sVarCalc nom de la variable à calculer - * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie - * @param rPrec précision de calcul - */ - private Solve(sVarCalc: string, rInit: number, rPrec: number): Result { - const dicho: Dichotomie = new Dichotomie(this, sVarCalc, this.DBG); - dicho.startIntervalMaxSteps = this._dichoStartIntervalMaxSteps; - const target = this.getFirstAnalyticalParameter(); - return dicho.Dichotomie(target.v, rPrec, rInit); - } - public get result(): Result { return this._result; } @@ -192,16 +186,20 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { public getReferencedParamValues(desc: string): ParamValues { const prm = this.getParameter(desc); - if (prm !== undefined) + if (prm !== undefined) { return prm.paramValues; + } return undefined; } public getReferencedResult(desc?: string): Result { - if (desc === undefined || (this._result !== undefined && this._result.name === desc)) + if (desc === undefined || (this._result !== undefined && this._result.name === desc)) { return this._result; + } - return this.CalcSerie(0.001, 0.1, desc); // il y a des valeurs par défaut pour la précision et la valeur initiale, mais il faudra prévoir un mécanisme pour les transmettre + // il y a des valeurs par défaut pour la précision et la valeur initiale, + // mais il faudra prévoir un mécanisme pour les transmettre + return this.CalcSerie(0.001, 0.1, desc); } public getReferencedExtraResult(desc: string): any { @@ -218,26 +216,29 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { public getReferencedObject(desc: string): NamedIterableValues { const tmp = desc.split("."); - if (tmp.length == 1) // paramètre (ex "Q") + if (tmp.length === 1) { + // paramètre (ex "Q") return this.getParameter(desc); + } - if (tmp[1] === "") // résultat (ex "Q.") - if (this._result !== undefined) + if (tmp[1] === "") { + // résultat (ex "Q.") + if (this._result !== undefined) { return this._result; + } + } // les autres objets référençables n'implémentant pas IJalhydObject... return undefined; } - private addPrefix(str: string, prefix: string) { - return prefix === undefined ? str : `${prefix}${str}`; - } - /** * liste des valeurs (paramètre, résultat, résultat complémentaire) liables à un paramètre * @param src objet qui sert de clé de recherche des paramètres liables, de type INamedObject | string - * @param excludeResult true si on veut exclure des valeurs retournées le résultat/résultat complémentaire correspondant à la clé de recherche - * @returns tableau d'objets de la forme { "name":string, "value":NamedIterableValues, "nub":Nub}, nub=Nub d'origine de la "value" + * @param excludeResult true si on veut exclure des valeurs retournées le résultat/résultat complémentaire + * correspondant à la clé de recherche + * @returns tableau d'objets de la forme { "name":string, "value":NamedIterableValues, "nub":Nub}, + * nub=Nub d'origine de la "value" */ public getLinkableValues(src: any, prefix?: string, excludeResult: boolean = false): any[] { const res: any[] = []; @@ -249,8 +250,9 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { // paramètres for (const p of this._prms) { - const cond = hasUid ? p.uid !== src.uid : true; // pour éviter d'ajouter le paramètre d'entrée dans le tableau résultat - if (cond) + // pour éviter d'ajouter le paramètre d'entrée dans le tableau résultat + const cond = hasUid ? p.uid !== src.uid : true; + if (cond) { switch (p.valueMode) { case ParamValueMode.SINGLE: case ParamValueMode.MINMAX: @@ -258,29 +260,61 @@ export abstract class Nub extends ComputeNode implements IReferencedNub { switch (name) { case "Z1": case "Z2": - if (p.symbol === "Z1" || p.symbol === "Z2") - res.push({ "name": this.addPrefix(p.symbol, prefix), "value": p, "nub": this }); + if (p.symbol === "Z1" || p.symbol === "Z2") { + res.push({ name: this.addPrefix(p.symbol, prefix), value: p, nub: this }); + } break; default: - if (p.symbol === name) - res.push({ "name": this.addPrefix(p.symbol, prefix), "value": p, "nub": this }); + if (p.symbol === name) { + res.push({ name: this.addPrefix(p.symbol, prefix), value: p, nub: this }); + } } } + } } // résultat if (this._result !== undefined && !excludeResult) { - if (this._result.name === name) - res.push({ "name": this.addPrefix(`${name}.`, prefix), "value": this._result, "nub": this }); + if (this._result.name === name) { + res.push({ name: this.addPrefix(`${name}.`, prefix), value: this._result, nub: this }); + } // résultats complémentaires - const erIter = this._result.getIterableExtraResults(name) - if (erIter !== undefined) - res.push({ "name": this.addPrefix(`${this._result.name}.${name}`, prefix), "value": erIter, "nub": this }); + const erIter = this._result.getIterableExtraResults(name); + if (erIter !== undefined) { + res.push({ name: this.addPrefix(`${this._result.name}.${name}`, prefix), value: erIter, nub: this }); + } } return res; } + + /** + * Résoud l'équation par une méthode numérique + * @param sVarCalc nom de la variable à calculer + * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie + * @param rPrec précision de calcul + */ + private Solve(sVarCalc: string, rInit: number, rPrec: number): Result { + const dicho: Dichotomie = new Dichotomie(this, sVarCalc, this.DBG); + dicho.startIntervalMaxSteps = this._dichoStartIntervalMaxSteps; + const target = this.getFirstAnalyticalParameter(); + return dicho.Dichotomie(target.v, rPrec, rInit); + } + + private addPrefix(str: string, prefix: string) { + return prefix === undefined ? str : `${prefix}${str}`; + } + + private setVariatedPrmValues(prmValues: ParamValues, variatedPrmValues: ParamValues, symbol: string) { + if (variatedPrmValues === undefined) { + return prmValues; + } else { + // tslint:disable-next-line:max-line-length + throw new Error(`CalcSerie() : il y plusieurs paramètres à varier : ${symbol}`); + } + } + } diff --git a/src/param/param-base.ts b/src/param/param-base.ts index 2d8ff743bbbde4813228a2cc495dd75fc4df46d8..63f49d778a693d451f1176b9e152eff7f3f439b5 100644 --- a/src/param/param-base.ts +++ b/src/param/param-base.ts @@ -1,14 +1,14 @@ import { Interval } from "../util/interval"; import { Message, MessageCode } from "../util/message"; -import { JalhydObject, IJalhydObject } from "../jalhyd_object" -import { ParamDomain, ParamDomainValue } from "./param-domain"; -import { ParamValues } from "./param-values"; -import { ParamValueMode } from "./param-value-mode"; -import { IReferencedNub, INubReference } from "../value_ref/object_ref"; +import { IJalhydObject, JalhydObject } from "../jalhyd_object"; +import { IObservable, Observable, Observer } from "../util/observer"; import { Result } from "../util/result"; +import { INubReference, IReferencedNub } from "../value_ref/object_ref"; +import { ParamDomain, ParamDomainValue } from "./param-domain"; import { NamedIterableValues, NumberIterator } from "./param-value-iterator"; -import { IObservable, Observable, Observer } from "../util/observer"; +import { ParamValueMode } from "./param-value-mode"; +import { ParamValues } from "./param-values"; /** * paramètre avec symbole et domaine de définition @@ -39,7 +39,7 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera super(); this._symbol = symb; - this._observable = new Observable() + this._observable = new Observable(); this._paramValues = new ParamValues(); this._paramValues.setSingleValue(val); @@ -66,8 +66,9 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera } public get paramValues(): ParamValues { - if (this.isReferenceDefined) + if (this.isReferenceDefined) { return this.referencedParamValues; + } return this._paramValues; } @@ -89,17 +90,6 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera return this._paramValues.currentValue; } - /** - * notification envoyée après la modification de la valeur du paramètre - */ - private notifyValueModified(sender: any) { - this.notifyObservers( - { - "action": "baseparamAfterValue", - }, sender - ); - } - public setValue(val: number, sender?: any) { this.checkValue(val); this._paramValues.currentValue = val; @@ -164,24 +154,6 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera } } - /** - * vérifie si un min/max est valide par rapport au domaine de définition - */ - private isMinMaxDomainValid(v: number): boolean { - if (v == undefined) - return false; - - if (this._paramValues.valueMode == ParamValueMode.MINMAX) - try { - this.checkValue(v); - } - catch (e) { - return false; - } - - return true; - } - public checkMin(min: number): boolean { return this.isMinMaxDomainValid(min) && (min < this._paramValues.max); } @@ -190,41 +162,22 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera return this.isMinMaxDomainValid(max) && (this._paramValues.min < max); } - private checkMinMax(min: number, max: number): boolean { - return this.isMinMaxDomainValid(min) && this.isMinMaxDomainValid(max) && (min < max); - } - - public get isMinMaxValid(): boolean { - return this.checkMinMax(this._paramValues.min, this._paramValues.max); - } - public checkStep(step: number): boolean { return this.isMinMaxValid && this._paramValues.stepRefValue.intervalHasValue(step); } - public get isValueValid(): boolean { + get isValueValid(): boolean { try { const v = this.getValue(); this.checkValue(v); return true; - } - catch (e) { + } catch (e) { return false; } } - private get isListValid(): boolean { - if (this._paramValues.valueList == undefined) - return false; - - for (let v of this._paramValues.valueList) - try { - this.checkValue(v); - } - catch (e) { - return false; - } - return true; + get isMinMaxValid(): boolean { + return this.checkMinMax(this._paramValues.min, this._paramValues.max); } public get isRangeValid(): boolean { @@ -236,6 +189,7 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera return this.checkStep(this._paramValues.step); } + // tslint:disable-next-line:max-line-length throw new Error(`"BaseParam.isRangeValid() : valeur ${ParamValueMode[this._paramValues.valueMode]} de ParamValueMode non prise en compte`); } @@ -252,20 +206,24 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera return true; case ParamValueMode.LINK: - if (!this.isReferenceDefined) + if (!this.isReferenceDefined) { return false; + } try { - for (const v of this.valuesIterator) + for (const v of this.valuesIterator) { this.checkValue(v); - return true - } - catch (e) { + } + return true; + } catch (e) { return false; } } - throw new Error(`"BaseParam.isValid() : valeur de ParamValueMode '${ParamValueMode[this._paramValues.valueMode]}' non prise en charge`); + throw new Error( + // tslint:disable-next-line:max-line-length + `BaseParam.isValid() : valeur de ParamValueMode '${ParamValueMode[this._paramValues.valueMode]}' non prise en charge` + ); } public get valueMode() { @@ -278,36 +236,13 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera // interface INubReference - /** - * vérifie l'absence de référence circulaire - * @param seenUids liste des uids déjà vérifiés - * @param o objet à tester (son uid est il déjà dans la liste ?) - */ - private checkReferenceCircularity(o: any, seenUids: number[]) { - if ("uid" in o) { - // if (o.uid in seenUids) - if (seenUids.indexOf(o.uid) !== -1) - throw new Error(`références circulaires détectées (uids : ${seenUids})`); - - seenUids.push(o.uid); - - if ("referencedObject" in o) { - const curr = o as INubReference; - const next = curr.referencedObject; - if (next !== undefined) - this.checkReferenceCircularity(next as IJalhydObject, seenUids); - } - } - } - public defineReference(target: IReferencedNub, desc: string) { const oldDef = this._paramValues.referenceDefinition; const oldTarget = this._paramValues.referencedNub; try { this._paramValues.defineReference(target, desc); this.checkReferenceCircularity(this, []); - } - catch (e) { + } catch (e) { this._paramValues.defineReference(oldTarget, oldDef); throw e; } @@ -317,43 +252,44 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera this._paramValues.undefineReference(); } - public get referenceDefinition(): string { + get referenceDefinition(): string { return this._paramValues.referenceDefinition; } - public get referencedNub(): IReferencedNub { + get referencedNub(): IReferencedNub { return this._paramValues.referencedNub; } - public get isReferenceDefined(): boolean { + get isReferenceDefined(): boolean { return this._paramValues.isReferenceDefined; } - public get referencedParamValues(): ParamValues { + get referencedParamValues(): ParamValues { return this._paramValues.referencedParamValues; } - public get referencedResult(): Result { + get referencedResult(): Result { return this._paramValues.referencedResult; } - public get referencedExtraResult(): any { + get referencedExtraResult(): any { return this._paramValues.referencedExtraResult; } - public get referencedValuesIterator(): NumberIterator { + get referencedValuesIterator(): NumberIterator { return this._paramValues.referencedValuesIterator; } - public get referencedObject(): NamedIterableValues { + get referencedObject(): NamedIterableValues { return this._paramValues.referencedObject; } // interface NamedIterableValues public get valuesIterator(): NumberIterator { - if (this.isReferenceDefined) + if (this.isReferenceDefined) { return this.referencedValuesIterator; + } return this._paramValues.valuesIterator; } @@ -384,7 +320,81 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera /** * notifie un événement aux observateurs */ - notifyObservers(data: any, sender?: any) { + public notifyObservers(data: any, sender?: any) { this._observable.notifyObservers(data, sender); } + + /** + * notification envoyée après la modification de la valeur du paramètre + */ + private notifyValueModified(sender: any) { + this.notifyObservers( + { + action: "baseparamAfterValue", + }, sender + ); + } + + /** + * vérifie si un min/max est valide par rapport au domaine de définition + */ + private isMinMaxDomainValid(v: number): boolean { + if (v === undefined) { + return false; + } + + if (this._paramValues.valueMode === ParamValueMode.MINMAX) { + try { + this.checkValue(v); + } catch (e) { + return false; + } + } + + return true; + } + + private checkMinMax(min: number, max: number): boolean { + return this.isMinMaxDomainValid(min) && this.isMinMaxDomainValid(max) && (min < max); + } + + private get isListValid(): boolean { + if (this._paramValues.valueList === undefined) { + return false; + } + + for (const v of this._paramValues.valueList) { + try { + this.checkValue(v); + } catch (e) { + return false; + } + } + return true; + } + + /** + * vérifie l'absence de référence circulaire + * @param seenUids liste des uids déjà vérifiés + * @param o objet à tester (son uid est il déjà dans la liste ?) + */ + private checkReferenceCircularity(o: any, seenUids: number[]) { + if ("uid" in o) { + // if (o.uid in seenUids) + if (seenUids.indexOf(o.uid) !== -1) { + throw new Error(`références circulaires détectées (uids : ${seenUids})`); + } + + seenUids.push(o.uid); + + if ("referencedObject" in o) { + const curr = o as INubReference; + const next = curr.referencedObject; + if (next !== undefined) { + this.checkReferenceCircularity(next as IJalhydObject, seenUids); + } + } + } + } + } diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts index 3cfde12f879738e1fbab0aa38e8a6b2167ff893f..1061c7b9b8d9f60e77a0fb6a929456d4d671e1cc 100644 --- a/src/param/param-definition.ts +++ b/src/param/param-definition.ts @@ -1,9 +1,8 @@ import { Message, MessageCode } from "../util/message"; - +import { Result } from "../util/result"; import { BaseParam } from "./param-base"; import { ParamDomain, ParamDomainValue } from "./param-domain"; import { ParamValueMode } from "./param-value-mode"; -import { Result } from "../util/result"; /** * calculabilité du paramètre @@ -53,16 +52,17 @@ export class ParamDefinition extends BaseParam { switch (this.referencedParamValues.valueMode) { case ParamValueMode.CALCUL: const r = this.referencedResult; - if (r.nbResultElements == 1) + if (r.nbResultElements === 1) { return r.resultElement.vCalc; + } throw new Error(`il n'y a pas exactement un ResultElement dans le Result "${r.name}"`); default: return this.referencedParamValues.currentValue; } - } - else if (ro instanceof Result) + } else if (ro instanceof Result) { return ro.vCalc; + } return this.referencedExtraResult; } diff --git a/src/param/param-value-iterator.ts b/src/param/param-value-iterator.ts index c5f05fcbf12acf15c3e56c4129a5823c4fe7578d..dceae1e5bf144c1cb3179e505f178c84c7c0e2cb 100644 --- a/src/param/param-value-iterator.ts +++ b/src/param/param-value-iterator.ts @@ -1,6 +1,6 @@ -import { ParamValues } from "./param-values"; -import { ParamValueMode } from "./param-value-mode"; import { INamedObject } from "../jalhyd_object"; +import { ParamValueMode } from "./param-value-mode"; +import { ParamValues } from "./param-values"; /** * itérateur sur des nombres @@ -65,7 +65,7 @@ export class ParamValueIterator implements NumberIterator { constructor(prm: ParamValues, reverse: boolean = false) { prm.check(); this._param = prm; - this.reset(reverse) + this.reset(reverse); } public reset(reverse: boolean) { @@ -79,10 +79,11 @@ export class ParamValueIterator implements NumberIterator { case ParamValueMode.MINMAX: this._config = 1; - if (reverse) + if (reverse) { this._index = this._param.max; - else + } else { this._index = this._param.min; + } break; case ParamValueMode.LISTE: @@ -99,7 +100,7 @@ export class ParamValueIterator implements NumberIterator { switch (this._config) { // valeur fixée case 0: - return this._index == 0; + return this._index === 0; // min/max case 1: @@ -125,21 +126,22 @@ export class ParamValueIterator implements NumberIterator { done: false, value: this._param.singleValue }; - } - else + } else { return { done: true, value: undefined }; + } // min/max case 1: const res = this._index; if (this.hasNext) { - if (this._reverse) + if (this._reverse) { this._index -= this._param.step; - else + } else { this._index += this._param.step; + } return { done: false, value: res diff --git a/src/param/param-values.ts b/src/param/param-values.ts index f30e70d5b2b9ae6e0dcfdb62f57e96ff3459fe00..366e9901795d0745ee371e01790f13867e8cc07c 100644 --- a/src/param/param-values.ts +++ b/src/param/param-values.ts @@ -1,9 +1,9 @@ -import { Pair } from "../util/pair" -import { DefinedNumber } from "../util/definedvalue"; -import { IReferencedNub, INubReference, NubReference } from "../value_ref/object_ref"; import { Result } from ".."; +import { DefinedNumber } from "../util/definedvalue"; +import { Pair } from "../util/pair"; +import { INubReference, IReferencedNub, NubReference } from "../value_ref/object_ref"; +import { IterableValues, NamedIterableValues, NumberIterator, ParamValueIterator } from "./param-value-iterator"; import { ParamValueMode } from "./param-value-mode"; -import { ParamValueIterator, IterableValues, NamedIterableValues, NumberIterator } from "./param-value-iterator"; export class ParamValues implements INubReference, IterableValues { /** @@ -59,7 +59,7 @@ export class ParamValues implements INubReference, IterableValues { public setValues(o: number | any, max?: number, step?: number) { if (typeof (o) === "number") { - if (max == undefined) { + if (max === undefined) { this._valueMode = ParamValueMode.SINGLE; this._singleValue.value = o as number; this._currentValue.value = o as number; @@ -70,14 +70,13 @@ export class ParamValues implements INubReference, IterableValues { this._stepValue = step; this._currentValue.undefine(); } - } - else if (Array.isArray(o)) { + } else if (Array.isArray(o)) { this._valueMode = ParamValueMode.LISTE; this._valueList = o; this._currentValue.undefine(); - } - else + } else { throw new Error(`ParamValues.setValues() : appel invalide`); + } } public get valueMode() { @@ -88,32 +87,33 @@ export class ParamValues implements INubReference, IterableValues { this._valueMode = m; } - private checkValueMode(expected: ParamValueMode) { - if (this._valueMode != expected) - throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[expected]} incorrect`); - } - public check() { switch (this._valueMode) { case ParamValueMode.SINGLE: - if (!this._singleValue.isDefined) + if (!this._singleValue.isDefined) { throw new Error(`ParamValues : valeur fixe non définie`); + } break; case ParamValueMode.MINMAX: - if (this._minValue == undefined) + if (this._minValue === undefined) { throw new Error(`ParamValues : valeur min non définie`); - if (this._maxValue == undefined) + } + if (this._maxValue === undefined) { throw new Error(`ParamValues : valeur max non définie`); - if (this._stepValue == undefined) + } + if (this._stepValue === undefined) { throw new Error(`ParamValues : valeur du pas non définie`); - if (this._minValue > this._maxValue) + } + if (this._minValue > this._maxValue) { throw new Error(`ParamValues : min > max`); + } break; case ParamValueMode.LISTE: - if (this._valueList == undefined) + if (this._valueList === undefined) { throw new Error(`ParamValues : liste de valeurs non définie`); + } break; case ParamValueMode.LINK: @@ -129,8 +129,9 @@ export class ParamValues implements INubReference, IterableValues { * valeur courante */ public get currentValue(): number { - if (this.isReferenceDefined) + if (this.isReferenceDefined) { return this._nubRef.referencedParamValues.currentValue; + } return this._currentValue.value; } @@ -142,8 +143,9 @@ export class ParamValues implements INubReference, IterableValues { * valeur dans le mode SINGLE */ public get singleValue(): number { - if (this.isReferenceDefined) + if (this.isReferenceDefined) { return this._nubRef.referencedParamValues.singleValue; + } return this._singleValue.value; } @@ -242,8 +244,8 @@ export class ParamValues implements INubReference, IterableValues { } /** - * - * @param reverse prépare un itérateur pour parcourir les valeurs + * prépare un itérateur pour parcourir les valeurs + * @param reverse */ public initIterator(reverse: boolean = false) { switch (this._valueMode) { @@ -252,8 +254,8 @@ export class ParamValues implements INubReference, IterableValues { this._iterator = this.getValuesIterator(reverse); break; - case ParamValueMode.LINK: - this._iterator = this._nubRef.referencedParamValues.getValuesIterator(reverse); + case ParamValueMode.CALCUL: + this._iterator = this._nubRef.referencedResult.valuesIterator; break; default: @@ -317,8 +319,9 @@ export class ParamValues implements INubReference, IterableValues { } public get referencedObject(): NamedIterableValues { - if (this.isReferenceDefined) + if (this.isReferenceDefined) { return this._nubRef.referencedObject; + } return undefined; } @@ -329,23 +332,34 @@ export class ParamValues implements INubReference, IterableValues { } public get hasMultipleValues(): boolean { - if (this.isReferenceDefined) - var it = this.referencedValuesIterator; - else { + let it; + if (this.isReferenceDefined) { + it = this.referencedValuesIterator; + } else { // dans certains cas (mode LINK mais aucune valeur liable compatible), on ne peut avoir d'itérateur - if (this._valueMode !== ParamValueMode.LINK) + if (this._valueMode !== ParamValueMode.LINK) { it = this.getValuesIterator(); + } } - if (it === undefined) + if (it === undefined) { return false; + } let n = 0; for (const v of it) { n++; - if (n > 1) + if (n > 1) { break; + } } return n > 1; } + + private checkValueMode(expected: ParamValueMode) { + if (this._valueMode !== expected) { + throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[expected]} incorrect`); + } + } + } diff --git a/src/util/result.ts b/src/util/result.ts index 6c4ac03d06b95d66e157aa39a5b004242b653ba0..a6c00a64135cc93d47f8d1061374c069c566068c 100644 --- a/src/util/result.ts +++ b/src/util/result.ts @@ -1,8 +1,8 @@ +import { JalhydObject } from "../jalhyd_object"; +import { NamedIterableValues, NumberIterator } from "../param/param-value-iterator"; import { cLog } from "./log"; import { Message, MessageCode, MessageSeverity } from "./message"; import { ResultElement } from "./resultelement"; -import { JalhydObject } from "../jalhyd_object"; -import { NamedIterableValues, NumberIterator } from "../param/param-value-iterator"; /** * Résultat global d'un calcul diff --git a/src/value_ref/object_ref.ts b/src/value_ref/object_ref.ts index b321604faacda0da1060ddf9d13a545697286afa..50e42681afa32889775cc4bf0ccfcbc82c29359a 100644 --- a/src/value_ref/object_ref.ts +++ b/src/value_ref/object_ref.ts @@ -1,13 +1,14 @@ -import { ParamValues } from "../param/param-values"; -import { Result } from ".."; -import { IJalhydObject } from "../jalhyd_object"; +import { Nub } from "../nub"; import { NamedIterableValues, NumberIterator } from "../param/param-value-iterator"; +import { ParamValues } from "../param/param-values"; +import { Result } from "../util/result"; /** * Nub dont certaines valeurs sont référençables pour réutilisation * (d'une calculette sur une autre par ex) */ export interface IReferencedNub { + /** * getter des valeurs * @param desc : description sous forme symbolique @@ -132,8 +133,9 @@ export class NubReference implements INubReference { * instance de ParamValues référencée */ public get referencedParamValues(): ParamValues { - if (!this.isReferenceDefined) + if (!this.isReferenceDefined) { return undefined; + } return this._referencedNub.getReferencedParamValues(this._refDefinition); } @@ -141,8 +143,9 @@ export class NubReference implements INubReference { * instance de Result référencée */ public get referencedResult(): Result { - if (!this.isReferenceDefined) + if (!this.isReferenceDefined) { return undefined; + } return this._referencedNub.getReferencedResult(this._refDefinition); } @@ -150,8 +153,9 @@ export class NubReference implements INubReference { * instance de résultat complémentaire référencée */ public get referencedExtraResult(): any { - if (!this.isReferenceDefined) + if (!this.isReferenceDefined) { return undefined; + } return this._referencedNub.getReferencedExtraResult(this._refDefinition); }