78 lines
1.5 KiB
JavaScript
78 lines
1.5 KiB
JavaScript
import * as I from 'immutable';
|
|
|
|
import {compose} from '@avocado/core';
|
|
import {Property} from '@avocado/mixins';
|
|
|
|
import {nextStep} from './next-step';
|
|
|
|
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, {
|
|
op,
|
|
path,
|
|
value: value[key],
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
const [key, substep] = nextStep(step);
|
|
this.patchStateStep(key, {
|
|
op: substep.op,
|
|
path: substep.path,
|
|
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) {
|
|
const children = this.synchronizedChildren();
|
|
for (const key of children) {
|
|
if (this[key] instanceof Synchronized) {
|
|
this[key].tick(elapsed);
|
|
}
|
|
}
|
|
this.state = this.state.withMutations((state) => {
|
|
for (const key of children) {
|
|
if (this[key] instanceof Synchronized) {
|
|
state.set(key, this[key].state);
|
|
}
|
|
else {
|
|
state.set(key, this[key]);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|