UNPKG

mudb

Version:

Real-time database for multiplayer games

175 lines 7.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const struct_1 = require("../schema/struct"); const union_1 = require("../schema/union"); class MuRDAStructStore { constructor(stores) { this.stores = stores; } state(rda, out) { const ids = Object.keys(this.stores); for (let i = 0; i < ids.length; ++i) { const id = ids[i]; out[id] = this.stores[id].state(rda.rdas[id], out[id]); } return out; } apply(rda, action) { return this.stores[action.type].apply(rda.rdas[action.type], action.data); } inverse(rda, action) { const result = rda.actionSchema.alloc(); result.type = action.type; const x = result.data = this.stores[action.type].inverse(rda.rdas[action.type], action.data); return result; } serialize(rda, out) { const ids = Object.keys(this.stores); for (let i = 0; i < ids.length; ++i) { const id = ids[i]; out[id] = this.stores[id].serialize(rda.rdas[id], out[id]); } return out; } free(rda) { const ids = Object.keys(this.stores); for (let i = 0; i < ids.length; ++i) { const id = ids[i]; this.stores[id].free(rda.rdas[id]); } } } exports.MuRDAStructStore = MuRDAStructStore; class MuRDAStruct { constructor(spec) { this._saveStore = null; this.rdas = spec; const stateSpec = {}; const actionSpec = {}; const storeSpec = {}; const emptyStores = {}; const props = Object.keys(spec); for (let i = 0; i < props.length; ++i) { const prop = props[i]; const rda = spec[prop]; stateSpec[prop] = rda.stateSchema; actionSpec[prop] = rda.actionSchema; storeSpec[prop] = rda.storeSchema; emptyStores[prop] = rda.emptyStore; } this.stateSchema = new struct_1.MuStruct(stateSpec); this.actionSchema = new union_1.MuUnion(actionSpec); this.storeSchema = new struct_1.MuStruct(storeSpec); this.emptyStore = new MuRDAStructStore(emptyStores); this.actionMeta = { type: 'store', action: { type: 'table', table: {}, }, }; const storeDispatch = {}; for (let i = 0; i < props.length; ++i) { const prop = props[i]; storeDispatch[prop] = this._wrapDispatch(prop, spec[prop]); } this.action = ((store) => { this._saveStore = store; return storeDispatch; }); } _wrapDispatch(id, rda) { const self = this; function wrapPartial(root, dispatch) { const savedPartial = { data: null }; function wrapPartialRec(meta, index) { if (meta.type === 'unit') { return (new Function('rda', 'partial', `/* ${id}:${index} */ return function() { var result = rda.actionSchema.alloc(); result.type = "${id}"; result.data = partial.data${index}.apply(null, arguments); return result; }`))(self, savedPartial); } else if (meta.type === 'table') { const result = {}; const keys = Object.keys(meta.table); for (let i = 0; i < keys.length; ++i) { const key = keys[i]; result[key] = wrapPartialRec(meta.table[key], `${index}["${key}"]`); } return result; } else if (meta.type === 'partial') { return wrapPartial(meta.action, (new Function('partial', `/* ${id}:${index} */ return function () { return partial.data${index}.apply(null, arguments); }`))(savedPartial)); } return {}; } return (new Function('dispatch', 'partial', 'wrappedDispatch', `/* ${id} */ return function () { partial.data = dispatch.apply(null, arguments); return wrappedDispatch; }`))(dispatch, savedPartial, wrapPartialRec(root, '')); } function wrapAction(meta, dispatch) { if (meta.type === 'unit') { return function (...args) { const result = self.actionSchema.alloc(); result.type = id; result.data = dispatch.apply(null, args); return result; }; } else if (meta.type === 'table') { const result = {}; const ids = Object.keys(meta.table); for (let i = 0; i < ids.length; ++i) { const key = ids[i]; result[key] = wrapAction(meta.table[key], dispatch); } return result; } else if (meta.type === 'partial') { return wrapPartial(meta.action, dispatch); } return {}; } function wrapStore(meta, index) { if (meta.type === 'unit') { return (new Function('rda', 'dispatch', `/* ${id}:${index} */ return function() { var result = rda.actionSchema.alloc(); result.type = "${id}"; result.data = dispatch(rda._saveStore.stores["${id}"])${index}.apply(null, arguments); return result; }`))(self, rda.action); } else if (meta.type === 'table') { const result = {}; const ids = Object.keys(meta.table); for (let i = 0; i < ids.length; ++i) { const key = ids[i]; result[key] = wrapStore(meta.table[key], `${index}["${key}"]`); } return result; } else if (meta.type === 'partial') { return wrapPartial(meta.action, (new Function('rda', 'dispatch', `/* ${id}:${index} */ return function() { return dispatch(rda._saveStore.stores["${id}"])${index}.apply(null, arguments); }`))(self, rda.action)); } return {}; } if (rda.actionMeta.type !== 'store') { this.actionMeta.action.table[id] = rda.actionMeta; return wrapAction(rda.actionMeta, rda.action); } else { this.actionMeta.action.table[id] = rda.actionMeta.action; return wrapStore(rda.actionMeta.action, ''); } } createStore(state) { const stores = {}; const ids = Object.keys(this.rdas); for (let i = 0; i < ids.length; ++i) { const id = ids[i]; stores[id] = this.rdas[id].createStore(state[id]); } return new MuRDAStructStore(stores); } parse(store) { const stores = {}; const ids = Object.keys(this.rdas); for (let i = 0; i < ids.length; ++i) { const id = ids[i]; stores[id] = this.rdas[id].parse(store[id]); } return new MuRDAStructStore(stores); } } exports.MuRDAStruct = MuRDAStruct; //# sourceMappingURL=struct.js.map