An error occurred while loading the file. Please try again.
-
Grand Francois authoredb78c00f8
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);
}
}