Skip to content

Instantly share code, notes, and snippets.

@AugustNagro
Created March 16, 2020 11:20
Show Gist options
  • Save AugustNagro/e6047a785de75bf83f2bc12faf39f1ed to your computer and use it in GitHub Desktop.
Save AugustNagro/e6047a785de75bf83f2bc12faf39f1ed to your computer and use it in GitHub Desktop.
class Prop {
constructor(writer, listeners) {
this.writer = writer;
this.listeners = listeners;
}
}
class PropReader {
constructor(name, changeListener, props) {
this._name = name;
this._changeListener = changeListener;
this._props = props;
this._registered = true;
}
get name() {
return this._name;
}
get registered() {
return this._registered;
}
/**
* Will return undefined until value is set. This method should
* not be frequently called
*/
get() {
const prop = this._props._map.get(this._name);
if (prop && (writer = prop.writer)) return writer._value;
return undefined;
}
register() {
if (this._registered) return false;
this._props._registerChangeListener(_this.name, this._changeListener);
this._registered = true;
return true;
}
unregister() {
if (!this._registered) return false;
const prop = this._props._map.get(this._name);
if (prop) {
prop.listeners.delete(this._changeListener);
}
this.registered = false;
return true;
}
}
class PropWriter {
constructor(name, listeners, props) {
this._name = name;
this._registered = true;
this._listeners = listeners;
this._props = props;
}
get name() {
return this._name;
}
get registered() {
return this._registered;
}
set(newValue) {
for (let l of this._listeners) {
l(newValue, this._value)
}
this._value = newValue;
}
unregister() {
if (!this._registered) return false;
const prop = this._props._map.get(this._name);
delete prop.writer;
this._registered = false;
return true;
}
}
export class Props {
constructor() {
this._map = new Map();
}
reader(name, changeListener) {
const reader = new PropReader(name, changeListener, this);
this._registerChangeListener(name, changeListener);
return reader;
}
_registerChangeListener(name, changeListener) {
let prop = this._map.get(name);
if (prop) {
prop.listeners.add(changeListener);
} else {
prop = new Prop(null, new Set().add(changeListener));
this._map.set(name, prop);
}
}
writer(name) {
let prop = this._map.get(name);
if (prop) {
if (prop.writer) throw 'Writer already exists for ' + name;
const w = new PropWriter(name, prop.listeners, this);
prop.writer = w;
return w;
}
const listeners = new Set();
const w = new PropWriter(name, listeners, this);
prop = new Prop(w, listeners);
this._map.set(name, prop);
return w;
}
}
export const props = new Props();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment