import * as I from 'immutable'; import {compose} from '@avocado/core'; import {Property} from '@avocado/mixins'; import {StateSynchronizer} from './synchronizer'; const decorate = compose( Property('state'), ); export class Synchronized extends decorate(class {}) { constructor() { super(); this.state = I.Map(); } synchronizedChildren() { return []; } patchState(patch) { for (const step of patch) { const {op, path, value} = step; if ('/' === path) { for (const key in value) { this.patchStateStep(key, {...step, value: value[key]}); } } else { const [key, substep] = StateSynchronizer.nextStep(step); this.patchStateStep(key, {...substep, value: substep.value}); } } } patchStateStep(key, step) { if (!(key in this)) { return; } if (this[key] instanceof Synchronized) { this[key].patchState([step]); } else { this[key] = step.value; } } tick(elapsed) { for (const key of this.synchronizedChildren()) { if (this[key] instanceof Synchronized) { this[key].tick(elapsed); this.state = this.state.set(key, this[key].state); } else { this.state = this.state.set(key, this[key]); } } } }