param-values.ts 7.39 KiB
import { ExtensionStrategy } from "./param-definition";
import { INumberIterator, IterableValues, ParamValueIterator } from "./param-value-iterator";
import { ParamValueMode } from "./param-value-mode";
/**
 * Represents the value(s) taken by a Parameter, along with and depending on
 * the value mode; linked values are not managed here, only the LINK value
 * mode is defined here
 */
export class ParamValues implements IterableValues {
    /** usually set by enclosing ParamDefinition */
    public valueMode: ParamValueMode;
    /** usually set by enclosing ParamDefinition */
    public extensionStrategy: ExtensionStrategy;
    /** valeur min dans le cas ParamValueMode.MINMAX */
    public min: number;
    /** valeur max dans le cas ParamValueMode.MINMAX */
    public max: number;
    /** pas de progression dans le cas ParamValueMode.MINMAX */
    public step: number;
    /** liste de valeurs dans le cas ParamValueMode.LISTE */
    public valueList: number[];
    /** valeur numérique (éventuellement non définie) dans le mode "valeur unique" (ParamValueMode.SINGLE) */
    private _singleValue: number;
    /** valeur courante (éventuellement non définie) indépendemment du mode */
    private _currentValue: number;
    /**
     * itérateur courant
    private _iterator: INumberIterator;
    public get singleValue(): number {
        return this._singleValue;
    public set singleValue(v: number) {
        this._singleValue = v;
        this._currentValue = v;
    public get currentValue() {
        return this._currentValue;
    public count() {
        return this._iterator.count();
    public setValues(o: number | any, max?: number, step?: number) {
        if (typeof (o) === "number") {
            if (max === undefined) {
                this.valueMode = ParamValueMode.SINGLE;
                this.singleValue = o;
            } else {
                this.valueMode = ParamValueMode.MINMAX;
                this.min = o;
                this.max = max;
                this.step = step;
        } else if (Array.isArray(o)) {
            this.valueMode = ParamValueMode.LISTE;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
this.valueList = o; } else { throw new Error(`ParamValues.setValues() : appel invalide`); } } public check() { switch (this.valueMode) { case ParamValueMode.SINGLE: if (this.singleValue === undefined) { throw new Error(`ParamValues : valeur fixe non définie`); } break; case ParamValueMode.MINMAX: if (this.min === undefined) { throw new Error(`ParamValues : valeur min non définie`); } if (this.max === undefined) { throw new Error(`ParamValues : valeur max non définie`); } if (this.step === undefined) { throw new Error(`ParamValues : valeur du pas non définie`); } if (this.min > this.max) { throw new Error(`ParamValues : min > max`); } break; case ParamValueMode.LISTE: if (this.valueList === undefined) { throw new Error(`ParamValues : liste de valeurs non définie`); } break; case ParamValueMode.LINK: case ParamValueMode.CALCUL: default: break; } } /** * Returns values as a number list by running through the iterator, * taking in account reverse, extendTo and addLastStep if defined */ public getInferredValuesList(reverse: boolean = false, extendTo?: number, addLastStep: boolean = false) { if ([ ParamValueMode.MINMAX, ParamValueMode.LISTE ].includes(this.valueMode)) { // protection against infinite loops if ( this.step !== undefined && this.step > 0 && this.min !== undefined && this.min !== null && this.max !== undefined && this.max !== null ) { const it = this.initValuesIterator(reverse, extendTo, addLastStep); const values: number[] = []; for (const v of it) { values.push(v); } return values; } else { return []; } } throw new Error("ParamValues.getInferredValuesList() : incorrect value mode" + ParamValueMode[this.valueMode]); } // -- iterator-related methods /**
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
* Returns a ParamValueIterator over the current values * @param reverse if true, will iterate starting at the end * @param extendTo if defined, will extend values list until this boundary * @param addLastStep if true, if (max - min) is not a multiple of step, one more * iteration will be done return last value (max) */ public getValuesIterator( reverse: boolean = false, extendTo?: number, addLastStep: boolean = false ): INumberIterator { return new ParamValueIterator(this, reverse, extendTo, addLastStep); } // interface IterableValues public get valuesIterator(): INumberIterator { return this.getValuesIterator(false, undefined, true); } public get hasMultipleValues(): boolean { try { // will throw an error if no value is defined at all this.check(); } catch (e) { return false; } const it = this.getValuesIterator(); if (it) { let n = 0; for (const v of it) { n++; if (n > 1) { break; } } return n > 1; } else { return false; } } /** * Checks that values are in LIST or MINMAX mode, then retrieves an iterator * @param reverse if true, will iterate starting at the end * @param extendTo if defined, will extend values list until this boundary * @param addLastStep if true, if (max - min) is not a multiple of step, one more * iteration will be done return last value (max) */ public initValuesIterator( reverse: boolean = false, extendTo?: number, addLastStep: boolean = false ): INumberIterator { switch (this.valueMode) { case ParamValueMode.LISTE: case ParamValueMode.MINMAX: this._iterator = this.getValuesIterator(reverse, extendTo, addLastStep); break; default: throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[this.valueMode]} incorrect`); } return this._iterator; } /** * @return true si il reste des valeurs à parcourir par l'itérateur courant */
211212213214215216217218219220221222223224225226227228229230231232
public get hasNext(): boolean { return this._iterator.hasNext; } /** * fixe la valeur courante à la prochaine valeur à parcourir par l'itérateur courant * @return prochaine valeur à parcourir par l'itérateur courant */ public next(): IteratorResult<number> { let res; res = this._iterator.next(); if (!res.done) { this._currentValue = res.value; } return res; } public [Symbol.iterator](): IterableIterator<number> { return this; } }