aes70
Version:
A controller library for the AES70 protocol.
116 lines (102 loc) • 2.98 kB
JavaScript
import { Arguments } from './arguments.js';
import { observeProperty } from './observeProperty.js';
export class PropertyObserver {
constructor(o, propertyName, cacheSubscriptions) {
this.o = o;
this.propertyName = propertyName;
this.cacheSubscriptions = cacheSubscriptions;
this.property = o.get_properties().find_property(propertyName);
this._subscribers = [];
this._currentValue = null;
this._unsubscribe = null;
if (!this.property)
throw new Error(
`Could not find property ${propertyName} in ${o.ClassName}`
);
}
callSubscriber(cb, changeIndex) {
try {
cb(true, this._currentValue, changeIndex);
} catch (error) {
console.error('Subscriber to', this, 'threw and exception', error);
}
}
subscribe(callback) {
this._subscribers.push(callback);
if (this._unsubscribe === null) {
this._unsubscribe = observeProperty(
this.o,
this.property,
(ok, result, changeIndex) => {
if (ok) {
this._currentValue = result;
const subscribers = this._subscribers;
if (!subscribers.length) this.unsubscribeAll();
subscribers.forEach((cb) => this.callSubscriber(cb, changeIndex));
}
}
);
} else if (this._currentValue !== null) {
this.callSubscriber(callback);
}
return () => {
this._subscribers = this._subscribers.filter(
(entry) => entry !== callback
);
if (this.cacheSubscriptions) return;
if (!this._subscribers.length) this.unsubscribeAll();
};
}
subscribeReturnValue(index, callback) {
return this.subscribe((ok, value, changeIndex) => {
if (!ok) {
callback(ok, value);
} else {
if (changeIndex >= 0 && changeIndex !== index) return;
if (value instanceof Arguments) {
callback(true, value.item(index));
} else {
callback(false, new Error(`Cannot index ${value} with ${index}.`));
}
}
});
}
subscribeCurrent(callback) {
return this.subscribeReturnValue(0, callback);
}
subscribeMin(callback) {
return this.subscribeReturnValue(1, callback);
}
subscribeMax(callback) {
return this.subscribeReturnValue(2, callback);
}
subscribeValue(callback) {
return this.subscribe((ok, value, changeIndex) => {
if (ok) {
if (value instanceof Arguments) {
if (changeIndex > 0) return;
callback(ok, value.item(0));
} else {
callback(ok, value);
}
} else {
callback(ok, value);
}
});
}
unsubscribeAll() {
this._subscribers.length = 0;
this._currentValue = null;
const cleanup = this._unsubscribe;
if (cleanup) {
try {
cleanup();
} catch (error) {
console.error('Unsubscribe in', this, 'threw an exception', error);
}
}
}
dispose() {
this.unsubscribeAll();
}
}