Created
March 9, 2021 19:03
-
-
Save amb26/6bd05ef2306b36529cb0517a183d5fd6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| "use strict"; | |
| var fluid = require("infusion"); | |
| fluid.tangledMat = function (layersIn) { | |
| var that = { | |
| layers: layersIn || [ // Array of { | |
| // layer: Object|Array | |
| // name: String | |
| ], | |
| // root: lazily initialised from fluid.tangledMat.getRoot | |
| writeLayer: null, | |
| writeLayerIndex: -1 | |
| }; | |
| Object.setPrototypeOf(that, fluid.tangledMat); | |
| return that; | |
| }; | |
| fluid.registerNamespace("fluid.flatObject"); | |
| fluid.flatObject.dispatch0 = function (func, target) { | |
| return func(target); | |
| }; | |
| fluid.flatObject.dispatch1 = function (func, target, args) { | |
| return func(target, args[0]); | |
| }; | |
| fluid.flatObject.dispatch2 = function (func, target, args) { | |
| return func(target, args[0], args[1]); | |
| }; | |
| fluid.flatObject.dispatch3 = function (func, target, args) { | |
| return func(target, args[0], args[1], args[2]); | |
| }; | |
| fluid.flatObject.dispatch4 = function (func, target, args) { | |
| return func(target, args[0], args[1], args[2], args[3]); | |
| }; | |
| fluid.flatObject.makeProperties = function (namespace) { | |
| var methods = namespace.methods; | |
| return fluid.transform(methods, function (func) { | |
| var arity = func.length; | |
| var dispatcher = fluid.getGlobalValue("fluid.flatObject.dispatch" + arity); | |
| return { | |
| value: function () { | |
| return dispatcher(func, this, arguments); | |
| } | |
| }; | |
| }); | |
| }; | |
| fluid.flatObject.defineMethodProperties = function (namespace) { | |
| Object.defineProperties(namespace, fluid.flatObject.makeProperties(namespace)); | |
| }; | |
| fluid.registerNamespace("fluid.tangledMat.methods"); | |
| fluid.tangledMat.methods.addLayer = function (mat, layer, layerName) { | |
| console.log("addLayer with mat ", mat); | |
| mat.layers.push({ | |
| layer: layer, | |
| name: layerName | |
| }); | |
| }; | |
| fluid.tangledMat.methods.getRoot = function (mat) { | |
| if (!mat.root) { | |
| var target = mat.topValue([]); | |
| mat.root = mat.makeProxy([], target); | |
| } | |
| return mat.root; | |
| }; | |
| fluid.tangledMat.methods.pathToRoot = function (mat, path) { | |
| var root = mat.getRoot(); | |
| var togo = [root]; | |
| for (var i = 0; i < path.length - 1; ++i) { | |
| togo[i] = togo[i - 1][path[i]]; | |
| }; | |
| return togo; | |
| }; | |
| // Compute mat top value by searching from right to left at a given path, returns cell | |
| fluid.tangledMat.methods.topValue = function (mat, path) { | |
| for (var i = mat.layers.length - 1; i >= 0; --i) { | |
| var value = fluid.getImmediate(mat.layers[i].layer, path); | |
| if (value !== undefined) { | |
| return { | |
| value: value, | |
| layerIndex: i, | |
| layerName: mat.layers[i].name | |
| }; | |
| } | |
| } | |
| return undefined; | |
| }; | |
| /** Read what should be a member value of a "mat top" given the holder of the value, path to it and member name | |
| * @param {fluid.tangledMat} mat - Mat structure containing the value to be read | |
| * @param {String[]} path - Path to the value holding the member to be read | |
| * @param {Any} holder - Object holding value to be read - expected to be an existing "mat top" member | |
| * @param {String} member - Member name to be read | |
| * @return {Any|undefined} The read value | |
| */ | |
| fluid.tangledMat.methods.readMember = function (mat, path, holder, member) { | |
| var cached = holder[member]; | |
| if (cached) { | |
| return cached; | |
| } else { | |
| var longPath = path.concat(member); | |
| var cell = mat.topValue(longPath); | |
| if (cell) { | |
| if (!fluid.isPrimitive(cell.value)) { | |
| cell.proxy = mat.makeProxy(longPath, cell); | |
| } | |
| // NOTE: This is a site at which something interesting might happen - we expect "free space" contents of the | |
| // mat top to share references with underlying layer. If there is a mat update, we expect at that point that | |
| // the top forks. Note that what this is is a differential implementation of "applyImmutable" | |
| holder[member] = cell; | |
| return cell; | |
| } else { | |
| return undefined; | |
| } | |
| } | |
| }; | |
| fluid.tangledMat.ensureContainer = function (holder, seg, exemplar) { | |
| if (fluid.typeCode(holder[seg]) !== fluid.typeCode(exemplar)) { | |
| var newContainer = fluid.freshContainer(exemplar); | |
| holder[seg] = newContainer; | |
| } | |
| return holder[seg]; | |
| }; | |
| fluid.tangledMat.methods.getLayerMap = function (mat) { | |
| var root = fluid.tangledMat.getRoot(mat); | |
| }; | |
| fluid.tangledMat.methods.evaluateFully = function (mat) { | |
| }; | |
| fluid.tangledMat.methods.makeProxy = function (mat, path, target) { | |
| var proxy = new Proxy(target, { | |
| get: function (target, member) { | |
| var cache = mat.readMember(path, target, member); | |
| // TODO: eliminate conditional on every access | |
| return cache ? cache.proxy || cache.value : undefined; | |
| }, | |
| set: function (target, member, value) { | |
| if (!mat.writeLayerIndex === -1) { | |
| fluid.fail("Cannot write ", value, " to path ", path, " for mat without write layer set"); | |
| } else { | |
| var layer = mat.layers[mat.writeLayerIndex]; | |
| var pathToRoot = mat.pathToRoot(path); | |
| var move = layer; | |
| for (var i = 0; i < path.length - 1; ++i) { | |
| var seg = i === 0 ? "layer" : path[i - 1]; | |
| move = fluid.tangledMat.ensureContainer(move, seg, pathToRoot[i]); | |
| } | |
| move[member] = value; | |
| } | |
| } | |
| // TODO: need to add ownKeys() so that object can be stringified | |
| }); | |
| return proxy; | |
| }; | |
| fluid.tangledMat.methods.getMembers = function (mat, path) { | |
| return mat.layers.map(function (oneLayer) { | |
| return fluid.getImmediate(oneLayer, path); | |
| }); | |
| }; | |
| fluid.tangledMat.methods.findLayer = function (mat, layerName) { | |
| return mat.layers.findIndex(function (entry) { | |
| return entry.name === layerName; | |
| }); | |
| }; | |
| fluid.tangledMat.methods.setWriteableLayer = function (mat, layerName) { | |
| var index = mat.findLayer(layerName); | |
| mat.writeLayer = layerName; | |
| mat.writeLayerIndex = index; | |
| }; | |
| fluid.flatObject.defineMethodProperties(fluid.tangledMat); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment