UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

134 lines (115 loc) 3.35 kB
import JSReanimated from './JSReanimated'; import Mapper from './Mapper'; export default class MapperRegistry<T> { sortedMappers: Mapper<T>[] = []; mappers: Map<number, Mapper<T>> = new Map(); _module: JSReanimated; updatedSinceLastExecute = false; constructor(module: JSReanimated) { this._module = module; } startMapper(mapper: Mapper<T>): number { this.mappers.set(mapper.id, mapper); this.updatedSinceLastExecute = true; return mapper.id; } stopMapper(id: number): void { this.mappers.delete(id); this.updatedSinceLastExecute = true; } execute(): void { if (this.updatedSinceLastExecute) { this.updateOrder(); this.updatedSinceLastExecute = false; } for (let i = 0, len = this.sortedMappers.length; i < len; ++i) { const mapper = this.sortedMappers[i]; if (mapper.dirty) { mapper.execute(); } } } updateOrder(): void { const nodes = [...this.mappers.values()].map((mapper) => new Node(mapper)); const mappersById: Record<number, Mapper<T>> = {}; this.mappers.forEach((mapper) => { mappersById[mapper.id] = mapper; }); // create a graph from array of nodes for (let i = 0, nodesLen = nodes.length; i < nodesLen; ++i) { const node = nodes[i]; if (node.mapper.outputs.length === 0) { continue; } for (let j = 0; j < nodesLen; ++j) { const restNode = nodes[j]; if (i === j || restNode.mapper.inputs.length === 0) { continue; } for ( let outi = 0, outputsLen = node.mapper.outputs.length; outi < outputsLen; ++outi ) { for ( let resti = 0, restLen = restNode.mapper.inputs.length; resti < restLen; ++resti ) { if ( node.mapper.outputs[outi]._id === restNode.mapper.inputs[resti]._id ) { node.children.push(restNode); } } } } } const post: Record<number, number> = {}; let postCounter = 1; const dfs = (node: Node<T>) => { const index = nodes.indexOf(node); if (index === -1) { // this node has already been handled return; } ++postCounter; nodes.splice(index, 1); if (node.children.length === 0 && nodes.length > 0) { post[node.mapper.id] = postCounter++; dfs(nodes[0]); return; } for (let i = 0, len = node.children.length; i < len; ++i) { dfs(node.children[i]); } post[node.mapper.id] = postCounter++; }; while (nodes.length) dfs(nodes[0]); const postArray = Object.keys(post).map((key) => { const num = parseInt(key); return [num, post[num]]; }); postArray.sort((a, b) => { return b[1] - a[1]; }); // clear sorted mappers this.sortedMappers = []; for (let i = 0, len = postArray.length; i < len; ++i) { const [id] = postArray[i]; this.sortedMappers.push(mappersById[id]); } } get needRunOnRender(): boolean { return this.updatedSinceLastExecute; } } class Node<T> { mapper: Mapper<T>; children: Node<T>[]; constructor(mapper: Mapper<T>, children = []) { this.mapper = mapper; this.children = children; } }