Created
March 16, 2020 11:20
-
-
Save AugustNagro/e6047a785de75bf83f2bc12faf39f1ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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