From 8c6c58b43767db22e97f6021f078ca4af34bdd92 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 13 Jul 2017 10:49:25 +0200
Subject: [PATCH] ajout des classes DefinedValue, DefinedString,
 DefinedBoolean, DefinedNumber et NumericalString

---
 src/index.ts                      |  2 +
 src/param.ts                      | 62 ++++++++++++++++++----------
 src/section/section_circulaire.ts |  2 +-
 src/section/section_type.ts       |  2 +-
 src/util/definedvalue.ts          | 67 +++++++++++++++++++++++++++++++
 src/util/numericalstring.ts       | 60 +++++++++++++++++++++++++++
 6 files changed, 172 insertions(+), 23 deletions(-)
 create mode 100644 src/util/definedvalue.ts
 create mode 100644 src/util/numericalstring.ts

diff --git a/src/index.ts b/src/index.ts
index 2797000e..787b5dbd 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,3 +5,5 @@ export * from './cond_distri';
 export * from './dichotomie';
 export * from './lechaptcalmon';
 export * from './regime_uniforme';
+export * from './util/definedvalue';
+export * from './util/numericalstring';
diff --git a/src/param.ts b/src/param.ts
index 1020f76e..138b520b 100644
--- a/src/param.ts
+++ b/src/param.ts
@@ -1,4 +1,5 @@
 import { Debug, UndefinedError } from './base';
+import { DefinedNumber } from './util/definedvalue';
 
 /**
  * domaine de définition du paramètre
@@ -93,7 +94,7 @@ export enum ParamCalculability {
 /**
  * définition d'un paramètre
  */
-export class ParamDefinition {
+export class ParamDefinition extends DefinedNumber {
     /**
      * symbole
      */
@@ -117,10 +118,14 @@ export class ParamDefinition {
     /**
      * valeur du paramètre
      */
-    private _value: number;
+    //private _value: number;
+
+    // private static _idGen: number = 0; // A VIRER
+    // private _id: number; // A VIRER
 
     // constructor(s: string, d: ParamDomain, c: ParamCalculability, val: number = undefined) {
     constructor(s: string, d: any, val: number = undefined) {
+        super(val);
         this._symbol = s;
 
         if (d instanceof ParamDomain)
@@ -130,9 +135,16 @@ export class ParamDefinition {
 
         this._calc = undefined;
         this.checkValue(val);
-        this._value = val;
+        // this._value = val;
+
+        // this._id = ParamDefinition._idGen++; // A VIRER
+        // console.log("constructor param " + this._symbol + " id=" + this._id); // A VIRER
     }
 
+    // get id(): number {
+    //     return this._id;
+    // }
+
     /**
      * getter symbole
      */
@@ -180,22 +192,30 @@ export class ParamDefinition {
      * gestion de la valeur
      */
     get v(): number {
-        if (this._value == undefined)
+        // if (this._value == undefined)
+        if (!this.isDefined)
             throw new UndefinedError("value of '" + this._symbol + "' parameter is not defined");
-        return this._value;
+        // return this._value;
+        return this.getValue();
     }
 
     set v(val: number) {
+        //        if (val == undefined)
+        //            console.log("warning : setting parameter '" + this._symbol + "' to undefined value (use undefine() instead)");
+
         if (this.calculability == ParamCalculability.NONE)
             throw "value of '" + this._symbol + "' parameter cannot be changed";
         this.checkValue(val);
-        this._value = val;
-    }
+        // this._value = val;
+        this.setValue(val);
 
-    get uncheckedValue() {
-        return this._value;
+        //        console.log("setting param " + this._symbol + " id=" + this._id + " to " + val); // A VIRER
     }
 
+    // get uncheckedValue() {
+    //     return this._value;
+    // }
+
     checkValue(v: number) {
         let sDomain = ParamDomainValue[this._domain.domain];
 
@@ -230,15 +250,15 @@ export class ParamDefinition {
         }
     }
 
-    isDefined(): boolean {
-        return this._value != undefined;
-    }
+    // isDefined(): boolean {
+    //     return this._value != undefined;
+    // }
 
 
-    undefine() {
-        this._value = undefined;
-        // this._savedValue = undefined;
-    }
+    // undefine() {
+    //     this._value = undefined;
+    //     // this._savedValue = undefined;
+    // }
 
     /**
      * gestion du cache
@@ -260,11 +280,11 @@ export class ParamDefinition {
     }
     */
 
-    toString(): string {
-        if (this.isDefined())
-            return "" + this._value;
-        return "undefined";
-    }
+    // toString(): string {
+    //     if (this.isDefined())
+    //         return "" + this._value;
+    //     return "undefined";
+    // }
 }
 
 
diff --git a/src/section/section_circulaire.ts b/src/section/section_circulaire.ts
index 995b70c9..9bc49b07 100644
--- a/src/section/section_circulaire.ts
+++ b/src/section/section_circulaire.ts
@@ -132,7 +132,7 @@ export class cSnCirc extends acSection {
                 }
 
                 this.debug("circ.Calc_B() : PAS débordement");
-                if (this.prms.D.isDefined() && this.prms.Y.isDefined()) {
+                if (this.prms.D.isDefined && this.prms.Y.isDefined) {
                         //return this.prms.D.v * Math.sin(this.Calc("Alpha"));
                         let res = this.prms.D.v * Math.sin(this.Calc("Alpha"));
                         this.debug("circ.Calc_B() : res=" + res);
diff --git a/src/section/section_type.ts b/src/section/section_type.ts
index 19e287e7..0cb41d93 100644
--- a/src/section/section_type.ts
+++ b/src/section/section_type.ts
@@ -249,7 +249,7 @@ export abstract class acSection extends ComputeNode {
                 this.debug("in Calc(" + sDonnee + ", rY=" + rY + ") old " + sDonnee + "=" + this.arCalc[sDonnee]);
                 this.debug("this.Y=" + this.prms.Y.toString());
 
-                if (rY != undefined && (!this.prms.Y.isDefined() || rY != this.prms.Y.v)) {
+                if (rY != undefined && (!this.prms.Y.isDefined || rY != this.prms.Y.v)) {
                         this.prms.Y.v = rY;
                         // On efface toutes les données dépendantes de Y pour forcer le calcul
                         this.Reset(false);
diff --git a/src/util/definedvalue.ts b/src/util/definedvalue.ts
new file mode 100644
index 00000000..9ed0be44
--- /dev/null
+++ b/src/util/definedvalue.ts
@@ -0,0 +1,67 @@
+export class DefinedValue<T> {
+    private _value: T;
+
+    constructor(v: T = undefined) {
+        this.value = v;
+    }
+
+    get isDefined() {
+        return this._value != undefined;
+    }
+
+    undefine() {
+        this._value = undefined;
+    }
+
+    get uncheckedValue() {
+        return this._value;
+    }
+
+    /**
+     * fonction nécessitée par le fait qu'on ne peut pas appeller les accesseurs d'un parent
+     * ou que si l'un des 2 accesseurs est surchargé, il faut surcharger l'autre
+     * (et donc pour pouvoir éventuellement appeler l'accesseur parent)
+     */
+    protected getValue(): T {
+        if (this._value == undefined)
+            throw "undefined value";
+
+        return this._value;
+    }
+
+    /**
+     * fonction nécessitée par le fait qu'on ne peut pas appeller les accesseurs d'un parent
+     * ou que si l'un des 2 accesseurs est surchargé, il faut surcharger l'autre
+     * (et donc pour pouvoir éventuellement appeler l'accesseur parent)
+     */
+    protected setValue(v: T) {
+        this._value = v;
+    }
+
+    get value() {
+        return this.getValue();
+    }
+
+    set value(v: T) {
+        this.setValue(v);
+    }
+
+    toString(): string {
+        if (this.isDefined)
+            return String(this._value);
+
+        return "undefined";
+    }
+}
+
+export class DefinedBoolean extends DefinedValue<boolean>{
+}
+
+export class DefinedNumber extends DefinedValue<number>{
+}
+
+export class DefinedString extends DefinedValue<string>{
+    constructor(v: any = undefined) {
+        super(v == undefined ? v : String(v));
+    }
+}
diff --git a/src/util/numericalstring.ts b/src/util/numericalstring.ts
new file mode 100644
index 00000000..650bb15d
--- /dev/null
+++ b/src/util/numericalstring.ts
@@ -0,0 +1,60 @@
+import { DefinedValue, DefinedBoolean, DefinedString } from "./definedvalue";
+
+export class NumericalString extends DefinedString {
+    private _isNumericalFlag: DefinedBoolean;
+
+    constructor(s: any = undefined) {
+        super(s);
+    }
+
+    private get isNumericalFlag(): DefinedBoolean {
+        if (this._isNumericalFlag == undefined)
+            this._isNumericalFlag = new DefinedBoolean();
+        return this._isNumericalFlag;
+    }
+
+    private updateNumericalFlag() {
+        if (!this.isNumericalFlag.isDefined) {
+            this.isNumericalFlag.value = false;
+            if (this.isDefined) {
+                if (typeof this.value === "string") {
+                    this.isNumericalFlag.value = String(this.value).trim() !== "" && !isNaN(+this.value)
+                }
+            }
+        }
+    }
+
+    get isNumerical(): boolean {
+        this.updateNumericalFlag();
+        return this.isNumericalFlag.value;
+    }
+
+    /**
+     * nécessaire car si on surcharge un des accesseurs, il faut surcharger les 2 (merci Microsoft)
+     */
+    get value() {
+        return this.getValue();
+    }
+
+    set value(v: string) {
+        this.isNumericalFlag.undefine();
+        this.setValue(v);
+        // this.updateNumericalFlag();
+    }
+
+    get numericalValue(): number {
+        if (!this.isNumerical)
+            throw "invalid NumericString '" + this.uncheckedValue + "' value";
+        return +this.value;
+    }
+
+    get uncheckValueString(): string {
+        if (this.isDefined)
+            return this.uncheckedValue;
+        return "";
+    }
+
+    toString(): string {
+        return super.toString() + (this.isNumerical ? " [numerical]" : " [NOT numerical]");
+    }
+}
-- 
GitLab