🐛 Improve selection of near copies to sync

This commit is contained in:
Andrés Moya 2024-02-22 09:37:33 +01:00 committed by Andrey Antukh
parent 7dd0745429
commit c5f24331a3
3 changed files with 49 additions and 16 deletions

View file

@ -150,6 +150,22 @@
:else :else
(get-head-shape objects (get objects (:parent-id shape)) options)))) (get-head-shape objects (get objects (:parent-id shape)) options))))
(defn get-parent-heads
"Get all component heads that are ancestors of the shape, in top-down order
(include self if it's also a head)."
[objects shape]
(->> (cfh/get-parents-with-self objects (:id shape))
(filter ctk/instance-head?)
(reverse)))
(defn get-parent-copy-heads
"Get all component heads that are ancestors of the shape, in top-down order,
excluding mains (include self if it's also a head)."
[objects shape]
(->> (cfh/get-parents-with-self objects (:id shape))
(filter #(and (ctk/instance-head? %) (ctk/in-component-copy? %)))
(reverse)))
(defn get-instance-root (defn get-instance-root
"Get the parent shape at the top of the component instance (main or copy)." "Get the parent shape at the top of the component instance (main or copy)."
[objects shape] [objects shape]

View file

@ -117,6 +117,12 @@
[libraries component-id & {:keys [include-deleted?] :or {include-deleted? false}}] [libraries component-id & {:keys [include-deleted?] :or {include-deleted? false}}]
(some #(ctkl/get-component (:data %) component-id include-deleted?) (vals libraries))) (some #(ctkl/get-component (:data %) component-id include-deleted?) (vals libraries)))
(defn find-component-file
[file libraries component-file]
(if (and (some? file) (= component-file (:id file)))
file
(get libraries component-file)))
(defn get-component (defn get-component
"Retrieve a component from a library." "Retrieve a component from a library."
[libraries library-id component-id & {:keys [include-deleted?] :or {include-deleted? false}}] [libraries library-id component-id & {:keys [include-deleted?] :or {include-deleted? false}}]
@ -188,21 +194,30 @@
"Locate the nearest component in the local file or libraries, and retrieve the shape "Locate the nearest component in the local file or libraries, and retrieve the shape
referenced by the instance shape." referenced by the instance shape."
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}] [file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
(let [parent-heads (->> (cfh/get-parents-with-self (:objects page) (:id shape)) (let [find-ref-shape-in-head
(filter ctk/instance-head?)
(reverse))
find-ref-shape-in-head
(fn [head-shape] (fn [head-shape]
(let [head-file (if (and (some? file) (= (:component-file head-shape) (:id file))) (let [head-file (find-component-file file libraries (:component-file head-shape))
file
(get libraries (:component-file head-shape)))
head-component (when (some? head-file) head-component (when (some? head-file)
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))] (ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
(when (some? head-component) (when (some? head-component)
(get-ref-shape (:data head-file) head-component shape))))] (get-ref-shape (:data head-file) head-component shape))))]
(some find-ref-shape-in-head parent-heads))) (some find-ref-shape-in-head (ctn/get-parent-heads (:objects page) shape))))
(defn find-ref-component
"Locate the nearest component in the local file or libraries that is referenced by the
instance shape."
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
(let [find-ref-component-in-head
(fn [head-shape]
(let [head-file (find-component-file file libraries (:component-file head-shape))
head-component (when (some? head-file)
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
(when (some? head-component)
(when (get-ref-shape (:data head-file) head-component shape)
head-component))))]
(some find-ref-component-in-head (ctn/get-parent-copy-heads (:objects page) shape))))
(defn find-remote-shape (defn find-remote-shape
"Recursively go back by the :shape-ref of the shape until find the correct shape of the original component" "Recursively go back by the :shape-ref of the shape until find the correct shape of the original component"
@ -229,6 +244,13 @@
remote-shape remote-shape
(find-remote-shape component-container libraries remote-shape))))) (find-remote-shape component-container libraries remote-shape)))))
(defn direct-copy?
"Check if the shape is in a direct copy of the component (i.e. the shape-ref points to shapes inside
the component)."
[shape component page file libraries]
(let [ref-component (find-ref-component file page libraries shape :include-deleted? true)]
(true? (= (:id component) (:id ref-component)))))
(defn get-component-shapes (defn get-component-shapes
"Retrieve all shapes of the component" "Retrieve all shapes of the component"
[file-data component] [file-data component]

View file

@ -599,15 +599,10 @@
library (dm/get-in libraries [(:component-file shape-inst) :data]) library (dm/get-in libraries [(:component-file shape-inst) :data])
component (or (ctkl/get-component library (:component-id shape-inst)) component (or (ctkl/get-component library (:component-id shape-inst))
(and reset? (and reset?
(ctkl/get-deleted-component library (:component-id shape-inst)))) (ctkl/get-deleted-component library (:component-id shape-inst))))]
component-shape (ctn/get-component-shape (:objects container) shape-inst)]
(if (and (ctk/in-component-copy? shape-inst) (if (and (ctk/in-component-copy? shape-inst)
(or (= (:id component) (:component-id component-shape)) reset?)) ; In a normal sync, we don't want to sync remote mains, only near (or (ctf/direct-copy? shape-inst component container nil libraries) reset?)) ; In a normal sync, we don't want to sync remote mains, only direct/near
(let [redirect-shaperef (partial redirect-shaperef container libraries) (let [redirect-shaperef (partial redirect-shaperef container libraries)
library (dm/get-in libraries [(:component-file shape-inst) :data])
component (or (ctkl/get-component library (:component-id shape-inst))
(and reset?
(ctkl/get-deleted-component library (:component-id shape-inst))))
shape-main (when component shape-main (when component
(if (and reset? components-v2) (if (and reset? components-v2)