jalhyd
Version:
JaLHyd, a Javascript Library for Hydraulics
280 lines • 12.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParamValueIterator = void 0;
const internal_modules_1 = require("../internal_modules");
const internal_modules_2 = require("../internal_modules");
const internal_modules_3 = require("../internal_modules");
/**
* itérateur sur les (ou la) valeurs prises par un ParamValues
*/
class ParamValueIterator {
constructor(prm, reverse = false, extendTo, addLastStep = false) {
prm.check();
this._param = prm;
this.reset(reverse, extendTo, addLastStep);
}
get currentValue() {
return this._current;
}
/**
* Returns the number of elements in the iterator without altering it,
* by counting a copy of the iterator
*/
count() {
const itCopy = new ParamValueIterator(this._param, this._reverse, this._extendTo, this._addLastStep);
let length = 0;
for (const i of itCopy) {
length++;
}
return length;
}
/**
* Reinits the value 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)
*/
reset(reverse, extendTo, addLastStep = false) {
this._reverse = reverse;
this._extendTo = extendTo;
this._addLastStep = addLastStep;
this._xindex = 0;
this._minMaxLastValueReached = false;
switch (this._param.valueMode) {
case internal_modules_3.ParamValueMode.SINGLE:
this._index = 0;
break;
case internal_modules_3.ParamValueMode.MINMAX:
if (reverse) {
this._index = this._param.max;
}
else {
this._index = this._param.min;
}
break;
case internal_modules_3.ParamValueMode.LISTE:
this._index = 0;
break;
default:
// tslint:disable-next-line:max-line-length
throw new Error(`ParamValueIterator : mode ${internal_modules_3.ParamValueMode[this._param.valueMode]} incorrect`);
}
}
/**
* Same as next(), but sets _currentValue on attached ParamValues; to be
* used with dedicated iterators, for params having multiple links on them
* @see jalhyd#222
*/
nextValue() {
const res = this.next();
if (!res.done) {
this._param.setCurrentValueFromIterator(res.value);
}
return res;
}
next() {
if (this.hasNext) {
switch (this._param.valueMode) {
case internal_modules_3.ParamValueMode.SINGLE:
if (this.hasNext) {
this._current = this._param.singleValue;
this._index++;
this._xindex++;
return {
done: false,
value: this._current
};
}
else {
return {
done: true,
value: undefined
};
}
case internal_modules_3.ParamValueMode.LISTE:
if (this.hasNextWithoutExtension) { // default case
this._current = this._param.valueList[this._index++]; // what about _reverse ?
this._xindex++; // count values for possible extension
return {
done: false,
value: this._current
};
}
else { // no more real values
if (this._extendTo && this.hasNext) {
// extend
this._index++;
switch (this._param.extensionStrategy) {
case internal_modules_2.ExtensionStrategy.REPEAT_LAST:
// repeat last real value (do not change this._current)
return {
done: false,
value: this._current
};
case internal_modules_2.ExtensionStrategy.RECYCLE:
// loop over real values
if (this._xindex === undefined
|| this._xindex === this._param.valueList.length) {
this._xindex = 0;
}
this._current = this._param.valueList[this._xindex++];
return {
done: false,
value: this._current
};
default:
throw new Error(`ParamValueIterator.next() : no extension strategy (LISTE)`);
}
}
else {
return {
done: true,
value: undefined
};
}
}
case internal_modules_3.ParamValueMode.MINMAX:
// protection against infinite loops
if (this._param.step === 0) {
this._index = this._param.max;
return {
done: true,
value: this._current
};
}
// s'il reste des valeurs normales (sans extension, mais en comptant le lastStep)
if (this.hasNextWithoutExtension) {
// si on a atteint la dernière valeur sans compter le dernier pas
if (this._addLastStep && this.minMaxLastAlignedValueReached()) {
// on ajoute la dernière valeur
this._current = this._reverse ? this._param.min : this._param.max;
}
else {
// on ajoute / retranche un pas
this._current = this._index;
if (this._reverse) {
this._index -= this._param.step;
}
else {
this._index += this._param.step;
}
}
this._xindex++; // count values for possible extension
return {
done: false,
value: this._current
};
}
else { // no more real values
if (this._extendTo && this.hasNext) {
this._xindex++; // count values for possible extension
switch (this._param.extensionStrategy) {
case internal_modules_2.ExtensionStrategy.REPEAT_LAST:
// repeat last real value (do not change this._current)
return {
done: false,
value: this._current
};
case internal_modules_2.ExtensionStrategy.RECYCLE:
// loop over real values using a local iterator that does not extend
if (this._locExIt === undefined || !this._locExIt.hasNext) {
// create / rewind iterator
this._locExIt = this._param.getValuesIterator(this._reverse, undefined, this._addLastStep);
}
this._current = this._locExIt.next().value;
return {
done: false,
value: this._current
};
default:
throw new Error(`ParamValueIterator.next() : no extension strategy (MINMAX)`);
}
}
else { // end of iterator
return {
done: true,
value: undefined
};
}
}
default:
throw new Error(`ParamValueIterator.next() : internal error`);
}
}
else { // end of iterator
return {
done: true,
value: undefined
};
}
}
// interface IterableIterator
[Symbol.iterator]() {
return this;
}
get hasNext() {
return this.hasNextValue();
}
get hasNextWithoutExtension() {
return this.hasNextValue(true);
}
/**
* Returns true if iterator has at least one more value
* @param ignoreExtension if true, will consider only real values (those that were
* set up), including the possible extraStep, and ignore extended values
*/
hasNextValue(ignoreExtension = false) {
switch (this._param.valueMode) {
case internal_modules_3.ParamValueMode.SINGLE:
return this._index === 0;
case internal_modules_3.ParamValueMode.LISTE:
if (this._extendTo && !ignoreExtension) {
return this._index < this._extendTo;
}
else {
return this._index < this._param.valueList.length;
}
case internal_modules_3.ParamValueMode.MINMAX:
// si extension, compter le nombre de valeurs
if (this._extendTo && !ignoreExtension) {
return this._xindex < this._extendTo;
}
else {
// sinon, s'il y a un dernier pas à faire
return !this.minMaxLastValueReached();
}
default:
throw new Error(`ParamValueIterator.hasNext() : internal error`);
}
}
/**
* Returns true if last value that is a multiple of step was reached;
* it might still miss the lastStep if required
*/
minMaxLastAlignedValueReached() {
return this._reverse ?
this._index < this._param.min - this._param.step * 1E-7 :
this._index > this._param.max + this._param.step * 1E-7;
}
/**
* Returns true if last value was reached in MINMAX mode
*/
minMaxLastValueReached() {
if (!this._minMaxLastValueReached) {
// update flag
if (this._addLastStep) {
this._minMaxLastValueReached = this._reverse ?
(0, internal_modules_1.isEqual)(this._current, this._param.min, this._param.step * 1E-7) :
(0, internal_modules_1.isEqual)(this._current, this._param.max, this._param.step * 1E-7);
}
else {
this._minMaxLastValueReached = this.minMaxLastAlignedValueReached();
}
}
// return stored flag in any case
return this._minMaxLastValueReached;
}
}
exports.ParamValueIterator = ParamValueIterator;
//# sourceMappingURL=param-value-iterator.js.map