correspondence.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import * as React from "react";
  2. import {newVersionedModel} from "./versioned_model";
  3. import {TrivialParser} from "../parser/trivial_parser";
  4. import {Version} from "../onion/version";
  5. import {GraphState} from "../onion/graph_state";
  6. // Pure function
  7. // Replays all deltas in a version to compute the graph state of that version.
  8. function getGraphState(version: Version): GraphState {
  9. const graphState = new GraphState();
  10. for (const d of [...version].reverse()) {
  11. graphState.exec(d);
  12. }
  13. return graphState;
  14. }
  15. export function newCorrespondence({generateUUID, primitiveRegistry, cs, as}) {
  16. // const cs = newVersionedModel({readonly, generateUUID, primitiveRegistry});
  17. const {initialState, getReducer: getReducerOrig} = newVersionedModel({readonly: true, generateUUID, primitiveRegistry});
  18. const parser = new TrivialParser(primitiveRegistry, generateUUID);
  19. const corrMap: Map<Version,{csVersion:Version,asVersion:Version}> = new Map([
  20. [initialState.version, {csVersion: cs.initialState.version, asVersion: as.initialState.version}]
  21. ]);
  22. function getReducer([state, setState], csReducer, asReducer) {
  23. const {
  24. getReactComponents,
  25. callbacks: {
  26. gotoVersion: gotoVersionOrig,
  27. createAndGotoNewVersion,
  28. undo,
  29. redo,
  30. },
  31. } = getReducerOrig([state, setState]);
  32. const parse = (csDeltas, description: string) => {
  33. const [csGS, corrGS, asGS] = [csReducer.state.version, state.version, asReducer.state.version].map(v => getGraphState(v));
  34. const {corrDeltas, asDeltas} = parser.parse(csDeltas, csGS, corrGS, asGS);
  35. const csVersionPromise = new Promise<Version>(resolve => {
  36. csReducer.callbacks.createAndGotoNewVersion(csDeltas, description, resolve);
  37. });
  38. const corrVersionPromise = new Promise<Version>(resolve => {
  39. createAndGotoNewVersion(corrDeltas, description, resolve);
  40. });
  41. const asVersionPromise = new Promise<Version>(resolve => {
  42. if (asDeltas.length > 0) {
  43. asReducer.callbacks.createAndGotoNewVersion(asDeltas, "parse:"+description, resolve);
  44. } else {
  45. resolve(asReducer.state.version);
  46. }
  47. });
  48. // Remember which Corr version embeds which CS/AS versions:
  49. Promise.all([csVersionPromise, corrVersionPromise, asVersionPromise]).then(([csVersion, corrVersion, asVersion]) => {
  50. corrMap.set(corrVersion, {csVersion, asVersion});
  51. });
  52. };
  53. const render = (asDeltas, description: string) => {
  54. const [csGS, corrGS, asGS] = [csReducer.state.version, state.version, asReducer.state.version].map(v => getGraphState(v));
  55. const {corrDeltas, csDeltas} = parser.render(asDeltas, csGS, corrGS, asGS);
  56. const csVersionPromise = new Promise<Version>(resolve => {
  57. if (asDeltas.length > 0) {
  58. csReducer.callbacks.createAndGotoNewVersion(csDeltas, "render:"+description, resolve);
  59. } else {
  60. resolve(csReducer.state.version);
  61. }
  62. });
  63. const corrVersionPromise = new Promise<Version>(resolve => {
  64. createAndGotoNewVersion(corrDeltas, description, resolve);
  65. });
  66. const asVersionPromise = new Promise<Version>(resolve => {
  67. asReducer.callbacks.createAndGotoNewVersion(asDeltas, description, resolve);
  68. });
  69. // Remember which Corr version embeds which CS/AS versions:
  70. Promise.all([csVersionPromise, corrVersionPromise, asVersionPromise]).then(([csVersion, corrVersion, asVersion]) => {
  71. corrMap.set(corrVersion, {csVersion, asVersion});
  72. });
  73. };
  74. const gotoVersion = (corrVersion: Version) => {
  75. const {csVersion, asVersion} = corrMap.get(corrVersion)!;
  76. csReducer.callbacks.gotoVersion(csVersion);
  77. gotoVersionOrig(corrVersion);
  78. asReducer.callbacks.gotoVersion(asVersion);
  79. };
  80. return {
  81. state,
  82. getReactComponents,
  83. callbacks: {
  84. parse,
  85. render,
  86. gotoVersion,
  87. undo,
  88. redo,
  89. },
  90. };
  91. }
  92. return {
  93. initialState,
  94. getReducer,
  95. };
  96. }