Kaynağa Gözat

WIP: Improve parser, making it more correct (but still not 100% correct)

Joeri Exelmans 2 yıl önce
ebeveyn
işleme
b3c29daf9b
2 değiştirilmiş dosya ile 35 ekleme ve 23 silme
  1. 0 8
      src/onion/graph_state.ts
  2. 35 15
      src/parser/trivial_parser.ts

+ 0 - 8
src/onion/graph_state.ts

@@ -60,14 +60,6 @@ export class FanOutListener implements GraphStateListener {
 
 type IncomingEdgeDelta = EdgeCreation|EdgeUpdate|NodeDeletion;
 
-// class EdgeState {
-//   readonly source: NodeState;
-//   readonly label: string;
-//   target: NodeOrValueState;
-
-
-// }
-
 export class DummyListener implements GraphStateListener {
   createNode(ns: NodeState) {}
   createValue(vs: ValueState) {}

+ 35 - 15
src/parser/trivial_parser.ts

@@ -193,8 +193,9 @@ export class TrivialParser  {
 
           if (geometryLabels.includes(label)) {
             const updatedNodeId = edgeCreation.source.id.value;
-            const newGeometry = getGeometry(updatedNodeId);
-            if (newGeometry !== undefined) {
+            const updatedGeometry = getGeometry(updatedNodeId);
+            if (updatedGeometry !== undefined) {
+              const updatedSurface = updatedGeometry.w * updatedGeometry.h;
               const updatedAsNode = findCorrespondingAsNode(corrState.nodes.get(updatedNodeId) as INodeState);
 
               // 1. Check if existing parent links still hold
@@ -204,9 +205,10 @@ export class TrivialParser  {
                 const otherCsNodeState = findCorrespondingAsNode(otherAsNodeState, true);
                 const otherNodeId = otherCsNodeState.creation.id.value;
                 const otherGeometry = getGeometry(otherNodeId);
-                if (otherGeometry === undefined || !isInside(newGeometry, otherGeometry)) {
+                if (otherGeometry === undefined || !isInside(updatedGeometry, otherGeometry)) {
                   // parent relation no longer holds
                   console.log("deleting outgoing link...")
+                  // CORRECT: we'll find updatedAsNode's new parent in step 2.
                   const deleteLink = updatedAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", null); // deletes the edge
                   applyToState(corrState, deleteLink);
                   targetDeltas.push(...deleteLink);
@@ -217,11 +219,11 @@ export class TrivialParser  {
                 const otherCsNodeState = findCorrespondingAsNode(otherAsNodeState, true);
                 const otherNodeId = otherCsNodeState.creation.id.value;
                 const otherGeometry = getGeometry(otherNodeId);
-                // console.log({otherNodeState, otherNodeId, otherGeometry})
-                if (otherGeometry === undefined || !isInside(otherGeometry, newGeometry)) {
+                if (otherGeometry === undefined || !isInside(otherGeometry, updatedGeometry)) {
                   // parent relation no longer holds
                   const otherAsNode = findCorrespondingAsNode(corrState.nodes.get(otherNodeId) as INodeState);
                   console.log("deleting incoming link...")
+                  // WRONG (TODO): must also find otherAsNode's new parent.
                   const deleteLink = otherAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", null); // deletes the edge
                   applyToState(corrState, deleteLink);
                   targetDeltas.push(...deleteLink);
@@ -237,7 +239,8 @@ export class TrivialParser  {
                 }
                 const otherGeometry = getGeometry(otherNodeId);
                 if (otherGeometry !== undefined) {
-                  const inside = isInside(newGeometry, otherGeometry);
+                  const inside = isInside(updatedGeometry, otherGeometry);
+                  // CORRECT: For geometries that the updated geometry is inside of, we are only interested in the smallest of them:
                   if (inside) {
                     const surface = otherGeometry.w * otherGeometry.h;
                     if (surface < smallestSurface) {
@@ -245,13 +248,26 @@ export class TrivialParser  {
                       smallestParent = findCorrespondingAsNode(corrState.nodes.get(otherNodeId) as INodeState);
                     }
                   }
-                  const outside = isInside(otherGeometry, newGeometry);
+                  const outside = isInside(otherGeometry, updatedGeometry);
+                  // CORRECT: For geometries that are inside of our updated geometry, we should only "steal" their outgoing parent link if our updated geometry is smaller than their current parent.
                   if (outside) {
-                    console.log("creating link...")
                     const otherAsNode = findCorrespondingAsNode(corrState.nodes.get(otherNodeId) as INodeState);
-                    if (otherAsNode.getOutgoingEdges().get("hasParent") === undefined) {
-                      console.log("creating link...")
-                      const asParentLink = updatedAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", otherAsNode.asTarget());
+                    const otherCurrentParent = otherAsNode.getOutgoingEdges().get("hasParent");
+                    const otherCurrentParentSurface = (() => {
+                      // find surface area of existing parent of other geometry...
+                      if (otherCurrentParent === undefined || otherCurrentParent.type !== "node") {
+                        return Infinity;
+                      }
+                      const otherCurrentParentCs = findCorrespondingAsNode(otherCurrentParent as INodeState, true);
+                      const otherCurrentParentGeometry = getGeometry(otherCurrentParentCs.creation.id.value);
+                      if (otherCurrentParentGeometry === undefined) {
+                        return Infinity;
+                      }
+                      return otherCurrentParentGeometry.w * otherCurrentParentGeometry.h;
+                    })();
+                    if (updatedSurface < otherCurrentParentSurface) {
+                      console.log("updated geometry is on outside...");
+                      const asParentLink = otherAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", updatedAsNode.asTarget());
                       applyToState(corrState, asParentLink);
                       targetDeltas.push(...asParentLink);
                     }
@@ -259,9 +275,13 @@ export class TrivialParser  {
                 }
               }
               if (smallestParent !== null) {
-                const asParentLink = updatedAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", smallestParent.asTarget());
-                applyToState(corrState, asParentLink);
-                targetDeltas.push(...asParentLink);
+                const existingLink = updatedAsNode.getOutgoingEdges().get("hasParent");
+                if (existingLink !== smallestParent) {
+                  console.log("updated geometry is on inside...");
+                  const asParentLink = updatedAsNode.getDeltasForSetEdge(this.primitiveRegistry, "hasParent", smallestParent.asTarget());
+                  applyToState(corrState, asParentLink);
+                  targetDeltas.push(...asParentLink);
+                }
               }
             }
           }
@@ -279,7 +299,7 @@ export class TrivialParser  {
       sourceOverrides,
       targetOverrides,
     };
-    console.log(result);
+    // console.log(result);
     return result;
   }