var LotIface = require('./lot-iface'); var Type = require('./type'); var Value = require('./value'); /** * A value holder, it emits the changed signal when value is changed. * Also it can be linked with a lot value or another parameter. */ module.exports = new Class({ Properties: { /** * The parameter value. */ value: { type: null }, /** * The parameter type. */ type: { type: Type }, /** * Another parameter to bind with. */ param: { type: Object }, /** * A lot to bind with. */ lot: { type: LotIface }, /** * The field name in the lot. */ name: { type: String }, /** * Determines whether the link to the lot is unidirectional, ie, a * change in the lot updates the parameter but not viceversa. */ oneWay: { type: Boolean } } ,_value: undefined ,_type: null ,_param: null ,_lot: null ,_sourceLock: false ,_name: null ,_oneWay: false ,_setValue(newValue) { if (this._putValue(newValue)) this._notifyChanges(); } ,_putValue(newValue) { if (Value.simpleEquals(newValue, this._value)) return false; this._value = Value.simpleClone(newValue); return true; } ,_notifyChanges() { this._refreshLot(); this._refreshParam(); this.emit('changed', this._value); } ,_setType(type) { this._type = type; this._onLotChange(); } ,_onSourceChange(newValue) { if (this._oneTime && this._value !== undefined) return; this._sourceLock = true; this._setValue(newValue); this._sourceLock = false; } ,_setParam(param) { this.link({_lot: null}); this.link({_param: param}, {changed: this._onParamChange}); this._refreshParam(); } ,_onParamChange() { if (this._sourceLock || !this._param) return; this._onSourceChange(this._param.value); } ,_refreshParam() { if (this._sourceLock || !this._param || this._oneWay) return; this._sourceLock = true; this._param.value = this._value; this._sourceLock = false; } ,_setLot(lot) { this.link({_param: null}); this.link({_lot: lot}, {change: this._onLotChange}); this._onLotChange(); } ,_onLotChange() { if (this._sourceLock || !this._lot || !this._name) return; var newValue = this._lot.get(this._name, this._type); this._onSourceChange(newValue); } ,_refreshLot() { if (this._sourceLock || !this._name || !this._lot || this._oneWay) return; this._sourceLock = true; this._lot.set(this._name, this._value); this._sourceLock = false; } ,_setName(name) { this._name = name; this._onLotChange(); } });