監聽值變化並及時更新
阿新 • • 發佈:2021-07-10
//monitor.js
export default { variables: new Map(), callback: null, listener: null, running: false, onMessage(e) { const variables = e.data.variables; if(!(Array.isArray(variables))) return; for(let v of variables) if(v && v.name && v.value !== undefined) this.update(v.name, v.value); }, fromJSON(str) { if(typeof(str) != 'string') return null; try { return JSON.parse(str); } catch { return null } }, toJSON(obj, space) { return JSON.stringify(obj, null, space); }, convertType(type, value) { if(typeof(value) == type) return value; switch(type) { case 'table': if(!Array.isArray(value)) value = this.fromJSON(value); break; case 'object': value = this.fromJSON(value); break; case 'boolean': value = /^(false)|0$/i.test(value) ? false : Boolean(value); break; case 'number': value = isNaN(value) ? 0 : Number(value); break; default: value = this.toJSON(value); } return value; }, isInvalidType(type, value) { if(!['string', 'number', 'boolean', 'object', 'table'].includes(type)) return true; if(type == 'table' && Array.isArray(value)) return false; if(type == 'object' && !value) return true; if(typeof(value) == type) return false; return true; }, start(callback) { if(this.running) return; if(typeof(callback) == 'function') this.callback = callback; this.listener = e => this.onMessage(e); window.addEventListener('message', this.listener); this.running = true; }, stop() { if(this.listener) window.removeEventListener('message', this.listener); this.running = false; }, add(...variables) { for(let v of variables) this.variables.set(v.name, v); }, remove(...names) { for(let n of names) this.variables.delete(names); }, update(name, value, description, type) { if(!this.running || !this.variables.has(name)) return; const v = this.variables.get(name); if(typeof(type) == 'string' && type != v.type) v.type = type; if(typeof(description) == 'string' && description != v.description) v.description = description; value = this.convertType(v.type, value); if(this.isInvalidType(v.type, value)) return; if(value === v.value) return; const oldValue = v.value; v.value = value; if(this.callback) this.callback(name, value, oldValue); } }