param-base.ts 10.76 KiB
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 { Result } from "../util/result";
import { NamedIterableValues } from "./param-value-iterator";
import { IObservable, Observable, Observer } from "../util/observer";
/**
 * paramètre avec symbole et domaine de définition
// tslint:disable-next-line:max-classes-per-file
export class BaseParam extends JalhydObject implements INubReference, NamedIterableValues, IObservable {
    /**
     * symbole
    private _symbol: string;
    /**
     * domaine de définition
    private _domain: ParamDomain;
    /**
     * valeur(s) prise(s)
    private _paramValues: ParamValues;
    /**
     * implémentation par délégation de IObservable
    private _observable: Observable;
    constructor(symb: string, d: ParamDomain | ParamDomainValue, val?: number) {
        super();
        this._symbol = symb;
        this._observable = new Observable()
        this._paramValues = new ParamValues();
        this._paramValues.setSingleValue(val);
        if (d instanceof ParamDomain) {
            this._domain = d;
        } else {
            this._domain = new ParamDomain(d as ParamDomainValue);
        this.checkValue(val);
    get symbol(): string {
        return this._symbol;
    public getDomain(): ParamDomain {
        return this._domain;
    public get interval(): Interval {
        return this._domain.interval;
    public get paramValues(): ParamValues {
        if (this.isReferenceDefined)
            return this.referencedParamValues;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
return this._paramValues; } /** * gestion de la valeur */ public get isDefined(): boolean { return this._paramValues.isDefined; } public getValue(): number { if (!this._paramValues.isDefined) { const e = new Message(MessageCode.ERROR_PARAMDEF_VALUE_UNDEFINED); e.extraVar.symbol = this.symbol; throw e; } 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; this.notifyValueModified(sender); } public get uncheckedValue(): number { return this._paramValues.uncheckedValue; } public checkValue(v: number) { const sDomain = ParamDomainValue[this._domain.domain]; switch (this._domain.domain) { case ParamDomainValue.ANY: break; case ParamDomainValue.POS: if (v <= 0) { const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_POS); f.extraVar.symbol = this.symbol; f.extraVar.value = v; throw f; } break; case ParamDomainValue.POS_NULL: if (v < 0) { const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_POSNULL); f.extraVar.symbol = this.symbol; f.extraVar.value = v; throw f; } break; case ParamDomainValue.NOT_NULL: if (v === 0) { const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_NULL);
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
f.extraVar.symbol = this.symbol; throw f; } break; case ParamDomainValue.INTERVAL: const min = this._domain.minValue; const max = this._domain.maxValue; if (v < min || v > max) { const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_INTERVAL); f.extraVar.symbol = this.symbol; f.extraVar.value = v; f.extraVar.minValue = min; f.extraVar.maxValue = max; throw f; } break; default: const e = new Message(MessageCode.ERROR_PARAMDOMAIN_INVALID); e.extraVar.symbol = this.symbol; e.extraVar.domain = sDomain; throw e; } } /** * 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); } public checkMax(max: number): boolean { 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 { try { const v = this.getValue(); this.checkValue(v); return true; }
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
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; } public get isRangeValid(): boolean { switch (this._paramValues.valueMode) { case ParamValueMode.LISTE: return this.isListValid; case ParamValueMode.MINMAX: return this.checkStep(this._paramValues.step); } throw new Error(`"BaseParam.isRangeValid() : valeur ${ParamValueMode[this._paramValues.valueMode]} de ParamValueMode non prise en compte`); } public get isValid() { switch (this._paramValues.valueMode) { case ParamValueMode.SINGLE: return this.isValueValid; case ParamValueMode.MINMAX: case ParamValueMode.LISTE: return this.isRangeValid; case ParamValueMode.CALCUL: return true; case ParamValueMode.LINK: try { for (const v of this.valuesIterator) this.checkValue(v); return true } catch (e) { return false; } } throw new Error(`"BaseParam.isValid() : valeur de ParamValueMode '${ParamValueMode[this._paramValues.valueMode]}' non prise en charge`); } public get valueMode() { return this._paramValues.valueMode; } public set valueMode(m: ParamValueMode) { this._paramValues.valueMode = m; } // interface INubReference /** * vérifie l'absence de référence circulaire * @param seenUids liste des uids déjà vérifiés
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
* @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) { this._paramValues.defineReference(oldTarget, oldDef); throw e; } } public undefineReference() { this._paramValues.undefineReference(); } public get referenceDefinition(): string { return this._paramValues.referenceDefinition; } public get referencedNub(): IReferencedNub { return this._paramValues.referencedNub; } public get isReferenceDefined(): boolean { return this._paramValues.isReferenceDefined; } public get referencedParamValues(): ParamValues { return this._paramValues.referencedParamValues; } public get referencedResult(): Result { return this._paramValues.referencedResult; } public get referencedExtraResult(): any { return this._paramValues.referencedExtraResult; } public get referencedValuesIterator(): IterableIterator<number> { return this._paramValues.referencedValuesIterator; } public get referencedObject(): IJalhydObject { return this._paramValues.referencedObject; } // interface NamedIterableValues
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
public get valuesIterator(): IterableIterator<number> { if (this.isReferenceDefined) return this.referencedValuesIterator; return this._paramValues.valuesIterator; } public get name(): string { return this._symbol; } // interface IObservable /** * ajoute un observateur à la liste */ public addObserver(o: Observer) { this._observable.addObserver(o); } /** * supprime un observateur de la liste */ public removeObserver(o: Observer) { this._observable.removeObserver(o); } /** * notifie un événement aux observateurs */ notifyObservers(data: any, sender?: any) { this._observable.notifyObservers(data, sender); } }