An error occurred while loading the file. Please try again.
-
Mathias Chouet authored72902809
import { Nub } from "./nub";
import { ParamDefinition } from "./param/param-definition";
import { INamedIterableValues } from "./param/param-value-iterator";
import { ParamValueMode } from "./param/param-value-mode";
import { ParamValues } from "./param/param-values";
export class LinkedValue {
/** linked value metadata (ex: calculator title for GUI) */
public meta: any;
/** target Nub */
private _nub: Nub;
/** target value : ParamDefinition (possibly in CALC mode) | undefined (ExtraResults) */
private _element: INamedIterableValues;
/** parameter / result symbol (ex: "Q") */
private _symbol: string;
/** magic param values: proxy to target when target is a not a result, handcrafted fake object otherwise */
private _paramValues: ParamValues;
constructor(nub: Nub, element: INamedIterableValues, symbol: string, meta: any = {}) {
this._nub = nub;
this._element = element;
this._symbol = symbol;
this.meta = meta;
}
public get nub() { return this._nub; }
public get element() { return this._element; }
public get symbol() { return this._symbol; }
/**
* Returns true if targetted value is a ParamDefinition (in CALC mode or not),
* and not an extra result
*/
public isParameter(): boolean {
return (this.element instanceof ParamDefinition);
}
/**
* Returns true if targetted value is a ParamDefinition in CALC mode
* (might not have any value yet)
*/
public isResult(): boolean {
return (
this.isParameter()
&& (this.element as ParamDefinition).valueMode === ParamValueMode.CALCUL
);
}
/**
* Returns true if targetted value is a ParamDefinition in CALC mode,
* or in LINK mode targetting a result (might not have any value yet)
*/
public isCalculated(): boolean {
return (
this.isResult()
|| this.isExtraResult()
|| (
this.isParameter()
&& (this.element as ParamDefinition).valueMode === ParamValueMode.LINK
&& (this.element as ParamDefinition).referencedValue.isCalculated() // recursion
)
);
}
/**
* Returns true if targetted value is an extra result
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
* (might not have any value yet)
*/
public isExtraResult(): boolean {
return (
this.nub !== undefined
&& this.symbol !== undefined
&& ! this.isParameter()
);
}
/**
* Returns true if v and the current objects have the same :
* - Nub UID
* - symbol
* - value type (Parameter / Result)
* (ignores metadata)
* @param v
*/
public equals(v: LinkedValue): boolean {
return (
v
&& (v.nub.uid === this.nub.uid)
&& (v.symbol === this.symbol)
&& (
(v.element === undefined && this.element === undefined)
|| (
v.element !== undefined
&& this.element !== undefined
&& v.element.constructor.name === this.element.constructor.name
)
)
);
}
/**
* Returs the ParamValues for the linked Parameter if any, or a
* fake ParamValues object if the targetted element is a Result
* or ExtraResults.
* If target is a result and triggerChainComputation is true,
* triggers a chain computation to obtain the result
*/
public getParamValues(triggerChainComputation: boolean = false): ParamValues {
let ret: ParamValues;
// trigger computation ?
if (
(this.isExtraResult() || this.isResult())
&& triggerChainComputation
) {
this.nub.CalcSerie();
}
if (this.isParameter()) {
const targetParam = (this.element as ParamDefinition);
// target might be in CALC mode
if (targetParam.valueMode === ParamValueMode.CALCUL) {
// if already computed, expose handmade fake param values for iterability
if (this.nub.result) {
if (! this._paramValues) {
this._paramValues = new ParamValues();
// populate
if (targetParam.hasMultipleValues) {
const multipleRes = this.nub.result.getCalculatedValues();
this._paramValues.setValues(multipleRes);
} else {
const singleRes = this.nub.result.vCalc;
this._paramValues.setValues(singleRes);
}
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
// return local cache
ret = this._paramValues;
} else {
throw new Error("LinkedValue.getParamValues() - result not available");
}
} else {
// simple proxy to target parameter values; if target parameter is
// also a LINK, ParamDefinition.paramValues will recursively call
// LinkedValue.getParamValues() (this method)
ret = targetParam.paramValues;
}
} else if (this.isExtraResult()) {
// is result available ?
if (this.nub.result) {
// expose handmade fake param values for iterability
if (! this._paramValues) {
this._paramValues = new ParamValues();
// populate
if (this.nub.resultHasMultipleValues()) {
const multipleExtraRes = this.nub.result.getExtraResults(this.symbol);
this._paramValues.setValues(multipleExtraRes);
} else {
const singleExtraRes = this.nub.result.getExtraResult(this.symbol);
this._paramValues.setValues(singleExtraRes);
}
}
// return local cache
ret = this._paramValues;
} else {
throw new Error("LinkedValue.getParamValues() - extra result not available");
}
} else {
throw new Error("LinkedValue.getParamValues() - cannot determine nature of target");
}
return ret;
}
/**
* Returns the single value of this.paramValues; triggers a chain computation
* if required to obtain ParamValues
*/
public getValue(triggerChainComputation: boolean = false) {
const pv = this.getParamValues(triggerChainComputation);
return pv.singleValue;
}
/**
* Returns true if
* - a parameter is targetted and it has multiple values
* - a result / extra result is targetted and it has more than 1 value
*/
public hasMultipleValues(): boolean {
if (this.isParameter()) { // possibly in CALC mode, but ParamDefinition.hasMultipleValues takes care of it
return (this.element as ParamDefinition).hasMultipleValues;
} else if (this.isResult() || this.isExtraResult()) {
// guess if parent Nub has any variating parameter (linked or not)
return this.nub.resultHasMultipleValues();
}
return false;
}
/**
* Returns true if target value is available
*/
public isDefined() {
if (this.isExtraResult()) {
211212213214215216217218219220221222223224225
return (this.nub.result !== undefined);
} else {
return (this.element as ParamDefinition).isDefined;
}
}
/**
* When invalidating a Nub's result, parameters pointing to this result should
* invalidate their proxy paramValues too
*/
public invalidateParamValues() {
this._paramValues = undefined;
}
}