object_ref.ts 5.84 KiB
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";
import { Message, MessageCode } from "../util/message";
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;
    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 an extra result
     * (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
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
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 result is not yet computed 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()) { // simple proxy to parameter; target might be in CALC mode ret = (this.element as ParamDefinition).paramValues; } else if (this.isExtraResult()) { // is result available ? if (this.nub.result) { // handmade fake param values ret = new ParamValues(); if (this.nub.resultHasMultipleValues()) { const multipleExtraRes = this.nub.result.getExtraResults(this.symbol); ret.setValues(multipleExtraRes); } else { const singleExtraRes = this.nub.result.getExtraResult(this.symbol); ret.setSingleValue(singleExtraRes); } } else { throw new Error("LinkedValue.getParamValues() - result not available"); } } else { throw new Error("LinkedValue.getParamValues() - cannot determine nature of target"); } return ret; } /** * Returns the current value of this.paramValues; triggers a chain computation * if required to obtain ParamValues; throws an error if this.paramValues is * ultimately not defined */ public getValue(triggerChainComputation: boolean = false) { const pv = this.getParamValues(triggerChainComputation); if (! pv.isDefined) { const e = new Message(MessageCode.ERROR_PARAMDEF_LINKED_VALUE_UNDEFINED); e.extraVar.symbol = this.symbol;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
throw e; } return pv.currentValue; } /** * Returns the current multiple values list of this.paramValues; triggers a * chain computation if required to obtain ParamValues; throws an error if * this.paramValues is ultimately not defined */ public getValues(triggerChainComputation: boolean = false): number[] { const pv = this.getParamValues(triggerChainComputation); if (! pv.isDefined) { const e = new Message(MessageCode.ERROR_PARAMDEF_LINKED_VALUE_UNDEFINED); e.extraVar.symbol = this.symbol; throw e; } return pv.valueList; } /** * 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()) { 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; } }