UNPKG

sy-bind

Version:

A lightweight binding framework for Cocos Creator

374 lines 13.5 kB
import { ListMethodType } from "../../../src/enums/SyEnums.js"; import { SyContainer } from "../SyContainer.js"; import { SyPipeTree } from "./SyTree/SyPipeTree.js"; export class SyPipe { heads = new WeakMap(); pipes = new WeakMap(); trees = new WeakMap(); listheadtrees = new WeakMap(); listpipes = new WeakMap(); listMutants = new WeakMap(); indexpipes = new WeakMap(); listIndexNodes = new WeakMap(); constructor() { } //#region 提供几个内部属性设置的方法 //添加到heads中 head:WeakMap<t_pipe_leader,t_pipe> _getOrCreateHeads(head) { let headpipe = this.heads.get(head); if (headpipe === undefined) { this.heads.set(head, headpipe = this.createPipe()); } return headpipe; } //添加到pipes中 pipes:WeakMap<t_pipe_node,t_pipes> _addToPipes(node, pipe) { let pipeSet = this.pipes.get(node); if (pipeSet === undefined) { this.pipes.set(node, pipeSet = new Set()); } pipeSet.add(pipe); } //从pipes中移除 node的pipe,删除node下pipes.size = 0 的数据 _removeFromPipes(node, pipe) { let pipeSet = this.pipes.get(node); if (pipeSet === undefined) return; pipeSet.delete(pipe); if (pipeSet.size === 0) this.pipes.delete(node); } _createTree(headpipe, head) { let tree = this.trees.get(headpipe); if (tree === undefined) { this.trees.set(headpipe, tree = new SyPipeTree(head, headpipe)); this._addToPipes(head, headpipe); } else { throw new Error('aleady has a tree'); } } //添加到 listheads 中 listheads:WeakMap<t_pipe_head<any>,SyPipeTree<any>> _getOrCreateListHeadTrees(head) { let tree = this.listheadtrees.get(head); if (tree === undefined) { const headpipe = this.createPipe(); this.listheadtrees.set(head, tree = new SyPipeTree(head, headpipe)); } return tree; } //添加到 listMutant 中 listMutant:WeakMap<t_head_pipe,SyContainer<any>> _getOrCreatelistMutant(headpipe) { let conatiner = this.listMutants.get(headpipe); if (conatiner === undefined) { this.listMutants.set(headpipe, conatiner = new SyContainer()); } return conatiner; } //添加到 indexpipes 中 indexpipes:WeakMap<t_pipe_index,t_index_pipes> _addToIndexPipes(index, pipe) { let pipeSet = this.indexpipes.get(index); if (pipeSet === undefined) { this.indexpipes.set(index, pipeSet = new Set()); } pipeSet.add(pipe); } //从 indexpipes 中移除 node的pipe,删除node下pipes.size = 0 的数据 _removeFromIndexPipes(index, pipe) { let pipeSet = this.indexpipes.get(index); if (pipeSet === undefined) return; pipeSet.delete(pipe); if (pipeSet.size === 0) this.indexpipes.delete(index); } createPipe() { return Object.create(null); } // 优化交集算法:保持O(min(n,m))时间复杂度,避免不必要的复制 intersection(setA, setB) { // 增加引用相等性快速检查 //if (setA === setB) return new Set(setA); // 优化遍历顺序:总是遍历较小的集合 const [smaller, larger] = setA.size <= setB.size ? [setA, setB] : [setB, setA]; const result = new Set(); // 使用迭代器直接遍历避免中间数组转换 for (const elem of smaller) { if (larger.has(elem)) result.add(elem); // 提前退出优化:当已找到所有可能元素时 if (result.size === smaller.size) break; } return result; } //#endregion //#region normal //创建一颗树 getOrCreateTree(head) { let headpipe = this.heads.get(head); if (headpipe === undefined) { this.heads.set(head, headpipe = this.createPipe()); this._createTree(headpipe, head); } return this.trees.get(headpipe); } getRoot(pipe) { const tree = this.trees.get(pipe); if (tree === undefined) return { success: false, data: undefined, error: ' can not find this tree ' }; return { success: true, data: tree.root, }; } replaceNode(pipe, parent, oldObj, newObj) { const tree = this.trees.get(pipe); if (tree === undefined) return; const [oldSet, newSet] = tree.replaceObj(parent, oldObj, newObj); for (const oldObj of oldSet) { this._removeFromPipes(oldObj, pipe); } for (const newObject of newSet) { this._addToPipes(newObject, pipe); } } getOrCreateTreeNode(pipe, parentNode, index, prop) { const tree = this.trees.get(pipe); if (tree === undefined) return { success: false, error: ' can not find this tree ' }; if (!tree.hasNode(parentNode)) return { success: false, error: ' node is not in the tree' }; const node = tree.getOrCreateChild(parentNode, prop, index); this._addToPipes(index, pipe); return { success: true, data: node }; } //#endregion //#region list getOrCreateIndexTreeNode(tree, parentNode, index, prop) { if (!tree.hasNode(parentNode)) return { success: false, error: ' node is not in the tree' }; const node = tree.getOrCreateChild(parentNode, prop, index); this._addToIndexPipes(index, parentNode.pipe); return { success: true, data: node }; } getOrCreateHeadTree(head) { return this._getOrCreateListHeadTrees(head); } getOrCreatelistMutant(headpipe) { return this._getOrCreatelistMutant(headpipe); } getOrCreateIndexNode(tree, target, index) { const headpipe = tree.pipe; let indexMap = this.listpipes.get(headpipe); if (indexMap === undefined) { this.listpipes.set(headpipe, indexMap = new Map()); } let indexpipe = indexMap.get(index); if (indexpipe === undefined) { indexMap.set(index, indexpipe = this.createPipe()); let indexSet = this.indexpipes.get(target); if (indexSet === undefined) { this.indexpipes.set(target, indexSet = new Set()); indexSet.add(indexpipe); } } return this.addOrCreateIndexNode(tree, indexpipe, target, index); } getIndexNode(tree, index) { const headpipe = tree.pipe; const indexpipe = this.listpipes.get(headpipe)?.get(index); if (indexpipe === undefined) { return undefined; } return this.listIndexNodes.get(indexpipe); } addOrCreateIndexNode(tree, indexpipe, obj, prop) { let node = this.listIndexNodes.get(indexpipe); if (node === undefined) { this.listIndexNodes.set(indexpipe, node = tree.addChild(tree.root, prop, obj, indexpipe)); } return node; } //#endregion //#region share getPipeline(entrance, direction) { // 双重非空检查优化(逻辑修正) const entranceSet = this.pipes.get(entrance); const directionSet = this.pipes.get(direction); // 短路返回优化:合并条件判断 if (!entranceSet || !directionSet) return undefined; // 增加空集快速通道 if (entranceSet.size === 0 || directionSet.size === 0) { return new Set(); } return this.intersection(entranceSet, directionSet); } getIndexPipeline(entrance, direction) { const entranceSet = this.indexpipes.get(entrance); const directionSet = this.indexpipes.get(direction); if (!entranceSet || !directionSet) return undefined; if (entranceSet.size === 0 || directionSet.size === 0) { return new Set(); } return this.intersection(entranceSet, directionSet); } replaceIndexNode(pipe, parent, oldObj, newObj) { const indexNode = this.listIndexNodes.get(pipe); if (indexNode === undefined) return; const tree = indexNode.root; const [oldSet, newSet] = tree.replaceObj(parent, oldObj, newObj); for (const oldObj of oldSet) { this._removeFromIndexPipes(oldObj, pipe); } for (const newObject of newSet) { this._addToIndexPipes(newObject, pipe); } } getHeadpipe(head) { return this.listheadtrees.get(head); } getIndexPipes(index) { return this.indexpipes.get(index); } //先不管是不是值类型 //只考虑object headTrigger(tree, index, oldValue, value) { const conatiner = this._getOrCreatelistMutant(tree.pipe); //const node = index === ListMethodType.pop?null: this.getOrCreateIndexNode(tree,value,oldValue); //分为三种情况 //1 push if (index === ListMethodType.push) { const pushNode = this.headPush(tree, value, oldValue); conatiner.call(ListMethodType.push, pushNode); } //2 pop else if (index === ListMethodType.pop) { this.headPop(tree, oldValue); conatiner.call(ListMethodType.pop); } //3 change else if (index === ListMethodType.change) { this.headChange(tree, value, oldValue); //this.headIndexReplaceNode(tree,node!,value); } } listen(node, prop, fn, triggerImmediately = true, bindType) { //let structure = this.structures.get(pipe); // if (structure === undefined) return { // success :false, // error:'Is the object accidentally released due to abnormal pipeline structure?' // } return node.listen(prop, fn, triggerImmediately, bindType); } unListen(target, prop, bindType) { try { //获取pipe const pipeSet = this.pipes.get(target); if (pipeSet === undefined) return { success: true, code: -1 }; for (const pipe of pipeSet) { //this.structures.get(pipe)?.unListen(target,prop,bindType); } return { success: true }; } catch (e) { return { success: false, error: e.toString(), code: 404 }; } } trigger(target, prop, value) { //console.log('进入了 pipe 的 trigger') const pipes = this.pipes.get(target); if (pipes !== undefined) { // for(const pipe of pipes){ // this.structures.get(pipe)?.trigger(target,prop,value); // } //console.log('获取到了tree') for (const pipe of pipes) { this.trees.get(pipe)?.trigger(target, prop, value); } } else { //console.log('没有获取到 tree') } const indexpipes = this.indexpipes.get(target); const trees = new Set(); if (indexpipes !== undefined) { for (const indexpipe of indexpipes) { const tree = this.listIndexNodes.get(indexpipe)?.root; if (tree !== undefined) trees.add(tree); } } else { //console.log('没有获取到 node 1') } if (trees.size) { for (const tree of trees) { tree.trigger(target, prop, value); } } } //#endregion headPush(tree, value, index) { return this.getOrCreateIndexNode(tree, value, index); } headPop(tree, index) { //获取那个node需要pop const popNode = this.getIndexNode(tree, index); if (popNode === undefined) { return; } const indexpipe = popNode.pipe; const deleteSet = tree.removeNodeAndChild(popNode); for (const oldObj of deleteSet) { this._removeFromIndexPipes(oldObj, indexpipe); } } headChange(tree, value, index) { const changeNode = this.getOrCreateIndexNode(tree, value, index); const nodeSet = new Set(); const pipe = changeNode.pipe; nodeSet.add(changeNode); const [oldSet, newSet] = tree.processNodesOptimized(nodeSet, value); for (const oldObj of oldSet) { this._removeFromIndexPipes(oldObj, pipe); } for (const newObj of newSet) { this._addToIndexPipes(newObj, pipe); } } } //# sourceMappingURL=SyPipe.js.map