mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
✨ Add better workspace file indexing strategy
Improve file indexes initialization on workspace. Instead of initialize indexes for all pages only initialize indexes for the loaded page.
This commit is contained in:
@@ -6,14 +6,29 @@
|
|||||||
|
|
||||||
(ns app.common.files.indices
|
(ns app.common.files.indices
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
|
(defn- generate-index
|
||||||
|
"An optimized algorithm for calculate parents index that walk from top
|
||||||
|
to down starting from a provided shape-id. Usefull when you want to
|
||||||
|
create an index for the whole objects or subpart of the tree."
|
||||||
|
[index objects shape-id parents]
|
||||||
|
(let [shape (get objects shape-id)
|
||||||
|
index (assoc index shape-id parents)
|
||||||
|
parents (cons shape-id parents)]
|
||||||
|
(reduce (fn [index shape-id]
|
||||||
|
(generate-index index objects shape-id parents))
|
||||||
|
index
|
||||||
|
(:shapes shape))))
|
||||||
|
|
||||||
(defn generate-child-all-parents-index
|
(defn generate-child-all-parents-index
|
||||||
"Creates an index where the key is the shape id and the value is a set
|
"Creates an index where the key is the shape id and the value is a set
|
||||||
with all the parents"
|
with all the parents"
|
||||||
([objects]
|
([objects]
|
||||||
(generate-child-all-parents-index objects (vals objects)))
|
(generate-index {} objects uuid/zero []))
|
||||||
|
|
||||||
([objects shapes]
|
([objects shapes]
|
||||||
(let [shape->entry
|
(let [shape->entry
|
||||||
@@ -24,24 +39,25 @@
|
|||||||
(defn create-clip-index
|
(defn create-clip-index
|
||||||
"Retrieves the mask information for an object"
|
"Retrieves the mask information for an object"
|
||||||
[objects parents-index]
|
[objects parents-index]
|
||||||
(let [retrieve-clips
|
(let [get-clip-parents
|
||||||
|
(fn [shape]
|
||||||
|
(let [shape-id (dm/get-prop shape :id)]
|
||||||
|
(cond-> []
|
||||||
|
(or (and (cfh/frame-shape? shape)
|
||||||
|
(not (:show-content shape))
|
||||||
|
(not= uuid/zero shape-id))
|
||||||
|
(cfh/bool-shape? shape))
|
||||||
|
(conj shape)
|
||||||
|
|
||||||
|
(:masked-group shape)
|
||||||
|
(conj (get objects (->> shape :shapes first))))))
|
||||||
|
|
||||||
|
xform
|
||||||
|
(comp (map (d/getf objects))
|
||||||
|
(mapcat get-clip-parents))
|
||||||
|
|
||||||
|
populate-with-clips
|
||||||
(fn [parents]
|
(fn [parents]
|
||||||
(let [lookup-object (fn [id] (get objects id))
|
(into [] xform parents))]
|
||||||
get-clip-parents
|
|
||||||
(fn [shape]
|
|
||||||
(cond-> []
|
|
||||||
(or (and (= :frame (:type shape))
|
|
||||||
(not (:show-content shape))
|
|
||||||
(not= uuid/zero (:id shape)))
|
|
||||||
(cfh/bool-shape? shape))
|
|
||||||
(conj shape)
|
|
||||||
|
|
||||||
(:masked-group shape)
|
(d/update-vals parents-index populate-with-clips)))
|
||||||
(conj (get objects (->> shape :shapes first)))))]
|
|
||||||
|
|
||||||
(into []
|
|
||||||
(comp (map lookup-object)
|
|
||||||
(mapcat get-clip-parents))
|
|
||||||
parents)))]
|
|
||||||
(-> parents-index
|
|
||||||
(update-vals retrieve-clips))))
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
(->> (rx/from changes)
|
(->> (rx/from changes)
|
||||||
(rx/merge-map (fn [[page-id changes]]
|
(rx/merge-map (fn [[page-id changes]]
|
||||||
(log/debug :hint "update-indexes" :page-id page-id :changes (count changes))
|
(log/debug :hint "update-indexes" :page-id page-id :changes (count changes))
|
||||||
(mw/ask! {:cmd :index/update-page-index
|
(mw/ask! {:cmd :index/update
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:changes changes})))
|
:changes changes})))
|
||||||
(rx/catch (fn [cause]
|
(rx/catch (fn [cause]
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
[app.common.types.component :as ctc]
|
[app.common.types.component :as ctc]
|
||||||
[app.common.types.fills :as types.fills]
|
[app.common.types.fills :as types.fills]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctst]
|
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
@@ -70,7 +69,6 @@
|
|||||||
[app.main.features.pointer-map :as fpmap]
|
[app.main.features.pointer-map :as fpmap]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.router :as rt]
|
[app.main.router :as rt]
|
||||||
[app.main.worker :as mw]
|
|
||||||
[app.render-wasm :as wasm]
|
[app.render-wasm :as wasm]
|
||||||
[app.render-wasm.api :as api]
|
[app.render-wasm.api :as api]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
@@ -84,7 +82,7 @@
|
|||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(log/set-level! :debug)
|
(log/set-level! :trace)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Workspace Initialization
|
;; Workspace Initialization
|
||||||
@@ -158,18 +156,9 @@
|
|||||||
(->> (fpmap/resolve-file file)
|
(->> (fpmap/resolve-file file)
|
||||||
(rx/map :data)
|
(rx/map :data)
|
||||||
(rx/map process-fills)
|
(rx/map process-fills)
|
||||||
(rx/mapcat
|
(rx/map
|
||||||
(fn [{:keys [pages-index] :as data}]
|
(fn [data]
|
||||||
(->> (rx/from (seq pages-index))
|
(assoc file :data (d/removem (comp t/pointer? val) data))))))
|
||||||
(rx/mapcat
|
|
||||||
(fn [[id page]]
|
|
||||||
(let [page (update page :objects ctst/start-page-index)]
|
|
||||||
(->> (mw/ask! {:cmd :index/initialize-page-index :page page})
|
|
||||||
(rx/map (fn [_] [id page]))))))
|
|
||||||
(rx/reduce conj {})
|
|
||||||
(rx/map (fn [pages-index]
|
|
||||||
(let [data (assoc data :pages-index pages-index)]
|
|
||||||
(assoc file :data (d/removem (comp t/pointer? val) data))))))))))
|
|
||||||
|
|
||||||
(defn- check-libraries-synchronozation
|
(defn- check-libraries-synchronozation
|
||||||
[file-id libraries]
|
[file-id libraries]
|
||||||
@@ -280,6 +269,8 @@
|
|||||||
(ptk/reify ::fetch-bundle
|
(ptk/reify ::fetch-bundle
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ _ stream]
|
||||||
|
(log/debug :hint "fetch bundle" :file-id (dm/str file-id))
|
||||||
|
|
||||||
(let [stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream)]
|
(let [stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream)]
|
||||||
(->> (rx/zip (rp/cmd! :get-file {:id file-id :features features})
|
(->> (rx/zip (rp/cmd! :get-file {:id file-id :features features})
|
||||||
(get-file-object-thumbnails file-id))
|
(get-file-object-thumbnails file-id))
|
||||||
@@ -288,6 +279,7 @@
|
|||||||
(fn [[file thumbnails]]
|
(fn [[file thumbnails]]
|
||||||
(->> (resolve-file file)
|
(->> (resolve-file file)
|
||||||
(rx/map (fn [file]
|
(rx/map (fn [file]
|
||||||
|
(log/trace :hint "file resolved" :file-id file-id)
|
||||||
{:file file
|
{:file file
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:features features
|
:features features
|
||||||
@@ -357,6 +349,10 @@
|
|||||||
(rx/map deref)
|
(rx/map deref)
|
||||||
(rx/mapcat
|
(rx/mapcat
|
||||||
(fn [{:keys [file]}]
|
(fn [{:keys [file]}]
|
||||||
|
(log/debug :hint "bundle fetched"
|
||||||
|
:team-id (dm/str team-id)
|
||||||
|
:file-id (dm/str file-id))
|
||||||
|
|
||||||
(rx/of (dpj/initialize-project (:project-id file))
|
(rx/of (dpj/initialize-project (:project-id file))
|
||||||
(dwn/initialize team-id file-id)
|
(dwn/initialize team-id file-id)
|
||||||
(dwsl/initialize-shape-layout)
|
(dwsl/initialize-shape-layout)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
(rx/of (dwsh/add-shape shape {:no-select? (= tool :curve)}))
|
(rx/of (dwsh/add-shape shape {:no-select? (= tool :curve)}))
|
||||||
(if (cfh/frame-shape? shape)
|
(if (cfh/frame-shape? shape)
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> (mw/ask! {:cmd :selection/query
|
(->> (mw/ask! {:cmd :index/query-selection
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:rect (:selrect shape)
|
:rect (:selrect shape)
|
||||||
:include-frames? true
|
:include-frames? true
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
[app.common.types.components-list :as ctkl]
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.page :as ctp]
|
[app.common.types.page :as ctp]
|
||||||
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
[app.main.errors]
|
[app.main.errors]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.router :as rt]
|
[app.main.router :as rt]
|
||||||
|
[app.main.worker :as mw]
|
||||||
[app.render-wasm.shape :as wasm.shape]
|
[app.render-wasm.shape :as wasm.shape]
|
||||||
[app.util.http :as http]
|
[app.util.http :as http]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
@@ -56,16 +58,21 @@
|
|||||||
(some? metadata) (cf/resolve-file-media metadata)
|
(some? metadata) (cf/resolve-file-media metadata)
|
||||||
(some? fill-image) (cf/resolve-file-media fill-image))))))
|
(some? fill-image) (cf/resolve-file-media fill-image))))))
|
||||||
|
|
||||||
|
(defn- get-page-cache
|
||||||
|
[state file-id page-id]
|
||||||
|
(dm/get-in state [:workspace-cache [file-id page-id]]))
|
||||||
|
|
||||||
(defn- initialize-page*
|
(defn- initialize-page*
|
||||||
"Second phase of page initialization, once we know the page is
|
"Second phase of page initialization, once we know the page is
|
||||||
available in the state"
|
available in the state"
|
||||||
[file-id page-id page]
|
[file-id page-id]
|
||||||
(ptk/reify ::initialize-page*
|
(ptk/reify ::initialize-page*
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
;; selection; when user abandon the current page, the selection is lost
|
(let [state (dsh/update-page state file-id page-id #(update % :objects ctst/start-page-index))
|
||||||
(let [local (dm/get-in state [:workspace-cache [file-id page-id]] default-workspace-local)]
|
page (dsh/lookup-page state file-id page-id)
|
||||||
|
local (or (get-page-cache state file-id page-id) default-workspace-local)]
|
||||||
|
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :current-page-id page-id)
|
(assoc :current-page-id page-id)
|
||||||
(assoc :workspace-local (assoc local :selected (d/ordered-set)))
|
(assoc :workspace-local (assoc local :selected (d/ordered-set)))
|
||||||
@@ -75,11 +82,16 @@
|
|||||||
(update :workspace-layout layout/load-layout-flags)
|
(update :workspace-layout layout/load-layout-flags)
|
||||||
(update :workspace-global layout/load-layout-state))))
|
(update :workspace-global layout/load-layout-state))))
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/WatchEvent
|
||||||
(effect [_ _ _]
|
(watch [_ state _]
|
||||||
(let [uris (into #{} xf:collect-file-media (:objects page))]
|
(let [page (dsh/lookup-page state file-id page-id)
|
||||||
(->> (rx/from uris)
|
uris (into #{} xf:collect-file-media (:objects page))]
|
||||||
(rx/subs! #(http/fetch-data-uri % false)))))))
|
(rx/merge
|
||||||
|
(->> (rx/from uris)
|
||||||
|
(rx/map #(http/fetch-data-uri % false))
|
||||||
|
(rx/ignore))
|
||||||
|
(->> (mw/ask! {:cmd :index/initialize :page page})
|
||||||
|
(rx/ignore)))))))
|
||||||
|
|
||||||
(defn initialize-page
|
(defn initialize-page
|
||||||
[file-id page-id]
|
[file-id page-id]
|
||||||
@@ -89,9 +101,9 @@
|
|||||||
(ptk/reify ::initialize-page
|
(ptk/reify ::initialize-page
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(if-let [page (dsh/lookup-page state file-id page-id)]
|
(if (dsh/lookup-page state file-id page-id)
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (initialize-page* file-id page-id page)
|
(rx/of (initialize-page* file-id page-id)
|
||||||
(dwth/watch-state-changes file-id page-id)
|
(dwth/watch-state-changes file-id page-id)
|
||||||
(dwl/watch-component-changes))
|
(dwl/watch-component-changes))
|
||||||
(let [profile (:profile state)
|
(let [profile (:profile state)
|
||||||
|
|||||||
@@ -344,7 +344,7 @@
|
|||||||
|
|
||||||
(if (some? selrect)
|
(if (some? selrect)
|
||||||
(->> (ask-worker
|
(->> (ask-worker
|
||||||
{:cmd :selection/query
|
{:cmd :index/query-selection
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:rect selrect
|
:rect selrect
|
||||||
:include-frames? true
|
:include-frames? true
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
(let [value (get point coord)
|
(let [value (get point coord)
|
||||||
vbox @refs/vbox
|
vbox @refs/vbox
|
||||||
ranges [[(- value (/ 0.5 zoom)) (+ value (/ 0.5 zoom))]]]
|
ranges [[(- value (/ 0.5 zoom)) (+ value (/ 0.5 zoom))]]]
|
||||||
(->> (mw/ask! {:cmd :snaps/range-query
|
(->> (mw/ask! {:cmd :index/query-snap
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
:axis coord
|
:axis coord
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
(mapv #(vector (- % snap-accuracy)
|
(mapv #(vector (- % snap-accuracy)
|
||||||
(+ % snap-accuracy))))
|
(+ % snap-accuracy))))
|
||||||
vbox @refs/vbox]
|
vbox @refs/vbox]
|
||||||
(->> (mw/ask! {:cmd :snaps/range-query
|
(->> (mw/ask! {:cmd :index/query-snap
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
:axis coord
|
:axis coord
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
|
|
||||||
(defn select-shapes-area
|
(defn select-shapes-area
|
||||||
[page-id frame-id selected objects area]
|
[page-id frame-id selected objects area]
|
||||||
(->> (mw/ask! {:cmd :selection/query
|
(->> (mw/ask! {:cmd :index/query-selection
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
:include-frames? true
|
:include-frames? true
|
||||||
|
|||||||
@@ -194,7 +194,7 @@
|
|||||||
(if (mf/ref-val hover-disabled-ref)
|
(if (mf/ref-val hover-disabled-ref)
|
||||||
(rx/of nil)
|
(rx/of nil)
|
||||||
(->> (mw/ask-buffered!
|
(->> (mw/ask-buffered!
|
||||||
{:cmd :selection/query
|
{:cmd :index/query-selection
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:rect rect
|
:rect rect
|
||||||
:include-frames? true
|
:include-frames? true
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
[app.worker.import]
|
[app.worker.import]
|
||||||
[app.worker.index]
|
[app.worker.index]
|
||||||
[app.worker.messages :as wm]
|
[app.worker.messages :as wm]
|
||||||
[app.worker.selection]
|
|
||||||
[app.worker.snaps]
|
|
||||||
[app.worker.thumbnails]
|
[app.worker.thumbnails]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|||||||
@@ -9,26 +9,69 @@
|
|||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.changes :as ch]
|
[app.common.files.changes :as ch]
|
||||||
|
[app.common.geom.rect :as grc]
|
||||||
|
[app.common.logging :as log]
|
||||||
|
[app.common.time :as ct]
|
||||||
[app.worker.impl :as impl]
|
[app.worker.impl :as impl]
|
||||||
|
[app.worker.selection :as selection]
|
||||||
|
[app.worker.snap :as snap]
|
||||||
[okulary.core :as l]))
|
[okulary.core :as l]))
|
||||||
|
|
||||||
|
(log/set-level! :info)
|
||||||
|
|
||||||
(defonce state (l/atom {:pages-index {}}))
|
(defonce state (l/atom {:pages-index {}}))
|
||||||
|
|
||||||
(defmethod impl/handler :index/initialize-page-index
|
(defmethod impl/handler :index/initialize
|
||||||
[{:keys [page] :as message}]
|
[{:keys [page] :as message}]
|
||||||
(swap! state update :pages-index assoc (:id page) page)
|
(let [tpoint (ct/tpoint-ms)]
|
||||||
(impl/handler (assoc message :cmd :selection/initialize-page-index))
|
(try
|
||||||
(impl/handler (assoc message :cmd :snaps/initialize-page-index)))
|
(swap! state update :pages-index assoc (:id page) page)
|
||||||
|
(swap! state update ::selection selection/add-page page)
|
||||||
|
(swap! state update ::snap snap/add-page page)
|
||||||
|
|
||||||
(defmethod impl/handler :index/update-page-index
|
(finally
|
||||||
|
(let [elapsed (tpoint)]
|
||||||
|
(log/dbg :hint "page indexed" :id (:id page) :elapsed elapsed ::log/sync? true))))
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defmethod impl/handler :index/update
|
||||||
[{:keys [page-id changes] :as message}]
|
[{:keys [page-id changes] :as message}]
|
||||||
|
(let [tpoint (ct/tpoint-ms)]
|
||||||
|
(try
|
||||||
|
(let [old-page (dm/get-in @state [:pages-index page-id])
|
||||||
|
new-page (-> state
|
||||||
|
(swap! ch/process-changes changes false)
|
||||||
|
(dm/get-in [:pages-index page-id]))]
|
||||||
|
|
||||||
(let [old-page (dm/get-in @state [:pages-index page-id])
|
(swap! state update ::snap snap/update-page old-page new-page)
|
||||||
new-page (-> state
|
(swap! state update ::selection selection/update-page old-page new-page))
|
||||||
(swap! ch/process-changes changes false)
|
(finally
|
||||||
(dm/get-in [:pages-index page-id]))
|
(let [elapsed (tpoint)]
|
||||||
message (assoc message
|
(log/dbg :hint "page index updated" :id page-id :elapsed elapsed ::log/sync? true))))
|
||||||
:old-page old-page
|
nil))
|
||||||
:new-page new-page)]
|
|
||||||
(impl/handler (assoc message :cmd :selection/update-page-index))
|
;; FIXME: schema
|
||||||
(impl/handler (assoc message :cmd :snaps/update-page-index))))
|
|
||||||
|
(defmethod impl/handler :index/query-snap
|
||||||
|
[{:keys [page-id frame-id axis ranges bounds] :as message}]
|
||||||
|
(if-let [index (get @state ::snap)]
|
||||||
|
(let [match-bounds?
|
||||||
|
(fn [[_ data]]
|
||||||
|
(some #(or (= :guide (:type %))
|
||||||
|
(= :layout (:type %))
|
||||||
|
(grc/contains-point? bounds (:pt %))) data))
|
||||||
|
|
||||||
|
xform
|
||||||
|
(comp (mapcat #(snap/query index page-id frame-id axis %))
|
||||||
|
(distinct)
|
||||||
|
(filter match-bounds?))]
|
||||||
|
(into [] xform ranges))
|
||||||
|
[]))
|
||||||
|
|
||||||
|
;; FIXME: schema
|
||||||
|
|
||||||
|
(defmethod impl/handler :index/query-selection
|
||||||
|
[message]
|
||||||
|
(if-let [index (get @state ::selection)]
|
||||||
|
(selection/query index message)
|
||||||
|
[]))
|
||||||
|
|||||||
@@ -17,46 +17,62 @@
|
|||||||
[app.common.types.modifiers :as ctm]
|
[app.common.types.modifiers :as ctm]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.quadtree :as qdt]
|
[app.util.quadtree :as qdt]
|
||||||
[app.worker.impl :as impl]
|
[clojure.set :as set]))
|
||||||
[clojure.set :as set]
|
|
||||||
[okulary.core :as l]))
|
|
||||||
|
|
||||||
;; FIXME: performance shape & rect static props
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; IMPL
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(def ^:const padding-percent 0.10)
|
(def ^:const padding-percent 0.10)
|
||||||
|
|
||||||
(defonce state (l/atom {}))
|
(defn- index-shape
|
||||||
|
"A reducing function that ads a shape to the index"
|
||||||
|
[objects parents-index clip-index index shape]
|
||||||
|
(let [bounds
|
||||||
|
(cond
|
||||||
|
(and ^boolean (cfh/text-shape? shape)
|
||||||
|
^boolean (some? (:position-data shape))
|
||||||
|
^boolean (d/not-empty? (:position-data shape)))
|
||||||
|
(gst/shape->bounds shape)
|
||||||
|
|
||||||
(defn make-index-shape
|
:else
|
||||||
[objects parents-index clip-parents-index]
|
(grc/points->rect (:points shape)))
|
||||||
(fn [index shape]
|
|
||||||
(let [{:keys [x y width height]}
|
|
||||||
(cond
|
|
||||||
(and ^boolean (cfh/text-shape? shape)
|
|
||||||
^boolean (some? (:position-data shape))
|
|
||||||
^boolean (d/not-empty? (:position-data shape)))
|
|
||||||
(gst/shape->bounds shape)
|
|
||||||
|
|
||||||
:else
|
bound
|
||||||
(grc/points->rect (:points shape)))
|
#js {:x (dm/get-prop bounds :x)
|
||||||
|
:y (dm/get-prop bounds :y)
|
||||||
|
:width (dm/get-prop bounds :width)
|
||||||
|
:height (dm/get-prop bounds :height)}
|
||||||
|
|
||||||
shape-bound #js {:x x :y y :width width :height height}
|
shape-id
|
||||||
|
(dm/get-prop shape :id)
|
||||||
|
|
||||||
parents (get parents-index (:id shape))
|
frame-id
|
||||||
clip-parents (get clip-parents-index (:id shape))
|
(dm/get-prop shape :frame-id)
|
||||||
|
|
||||||
frame (when (and (not= :frame (:type shape))
|
shape-type
|
||||||
(not= (:frame-id shape) uuid/zero))
|
(dm/get-prop shape :type)
|
||||||
(get objects (:frame-id shape)))]
|
|
||||||
(qdt/insert index
|
|
||||||
(:id shape)
|
|
||||||
shape-bound
|
|
||||||
(assoc shape
|
|
||||||
:frame frame
|
|
||||||
:clip-parents clip-parents
|
|
||||||
:parents parents)))))
|
|
||||||
|
|
||||||
(defn objects-bounds
|
parents
|
||||||
|
(get parents-index shape-id)
|
||||||
|
|
||||||
|
clip-parents
|
||||||
|
(get clip-index shape-id)
|
||||||
|
|
||||||
|
frame
|
||||||
|
(when (and (not= :frame shape-type)
|
||||||
|
(not= frame-id uuid/zero))
|
||||||
|
(get objects frame-id))]
|
||||||
|
|
||||||
|
(qdt/insert index
|
||||||
|
shape-id
|
||||||
|
bound
|
||||||
|
(assoc shape
|
||||||
|
:frame frame
|
||||||
|
:clip-parents clip-parents
|
||||||
|
:parents parents))))
|
||||||
|
|
||||||
|
(defn- objects-bounds
|
||||||
"Calculates the bounds of the quadtree given a objects map."
|
"Calculates the bounds of the quadtree given a objects map."
|
||||||
[objects]
|
[objects]
|
||||||
(-> objects
|
(-> objects
|
||||||
@@ -64,7 +80,7 @@
|
|||||||
vals
|
vals
|
||||||
gsh/shapes->rect))
|
gsh/shapes->rect))
|
||||||
|
|
||||||
(defn add-padding-bounds
|
(defn- add-padding-bounds
|
||||||
"Adds a padding to the bounds defined as a percent in the constant `padding-percent`.
|
"Adds a padding to the bounds defined as a percent in the constant `padding-percent`.
|
||||||
For a value of 0.1 will add a 20% width increase (2 x padding)"
|
For a value of 0.1 will add a 20% width increase (2 x padding)"
|
||||||
[bounds]
|
[bounds]
|
||||||
@@ -81,41 +97,48 @@
|
|||||||
|
|
||||||
(defn- create-index
|
(defn- create-index
|
||||||
[objects]
|
[objects]
|
||||||
(let [shapes (-> objects (dissoc uuid/zero) vals)
|
(let [parents-index (cfi/generate-child-all-parents-index objects)
|
||||||
parents-index (cfi/generate-child-all-parents-index objects)
|
clip-index (cfi/create-clip-index objects parents-index)
|
||||||
clip-parents-index (cfi/create-clip-index objects parents-index)
|
root-shapes (cfh/get-immediate-children objects uuid/zero)
|
||||||
|
bounds (-> root-shapes gsh/shapes->rect add-padding-bounds)
|
||||||
root-shapes (cfh/get-immediate-children objects uuid/zero)
|
|
||||||
bounds (-> root-shapes gsh/shapes->rect add-padding-bounds)
|
|
||||||
|
|
||||||
index-shape (make-index-shape objects parents-index clip-parents-index)
|
|
||||||
initial-quadtree (qdt/create (clj->js bounds))
|
|
||||||
|
|
||||||
index (reduce index-shape initial-quadtree shapes)]
|
|
||||||
|
|
||||||
|
index (reduce-kv #(index-shape objects parents-index clip-index %1 %3)
|
||||||
|
(qdt/create (clj->js bounds))
|
||||||
|
(dissoc objects uuid/zero))]
|
||||||
{:index index :bounds bounds}))
|
{:index index :bounds bounds}))
|
||||||
|
|
||||||
|
;; FIXME: optimize
|
||||||
(defn- update-index
|
(defn- update-index
|
||||||
[{index :index :as data} old-objects new-objects]
|
[{index :index :as data} old-objects new-objects]
|
||||||
(let [changes? (fn [id]
|
(let [object-changed?
|
||||||
(not= (get old-objects id)
|
(fn [id]
|
||||||
(get new-objects id)))
|
(not= (get old-objects id)
|
||||||
|
(get new-objects id)))
|
||||||
|
|
||||||
changed-ids (into #{}
|
changed-ids
|
||||||
(comp (filter #(not= % uuid/zero))
|
(into #{}
|
||||||
(filter changes?)
|
(comp (filter #(not= % uuid/zero))
|
||||||
(mapcat #(into [%] (cfh/get-children-ids new-objects %))))
|
(filter object-changed?)
|
||||||
(set/union (set (keys old-objects))
|
(mapcat #(into [%] (cfh/get-children-ids new-objects %))))
|
||||||
(set (keys new-objects))))
|
|
||||||
|
|
||||||
shapes (->> changed-ids (mapv #(get new-objects %)) (filterv (comp not nil?)))
|
(set/union (set (keys old-objects))
|
||||||
parents-index (cfi/generate-child-all-parents-index new-objects shapes)
|
(set (keys new-objects))))
|
||||||
clip-parents-index (cfi/create-clip-index new-objects parents-index)
|
|
||||||
|
|
||||||
new-index (qdt/remove-all index changed-ids)
|
shapes
|
||||||
|
(->> changed-ids
|
||||||
|
(map #(get new-objects %))
|
||||||
|
(filterv (comp not nil?)))
|
||||||
|
|
||||||
index-shape (make-index-shape new-objects parents-index clip-parents-index)
|
parents-index
|
||||||
index (reduce index-shape new-index shapes)]
|
(cfi/generate-child-all-parents-index new-objects shapes)
|
||||||
|
|
||||||
|
clip-index
|
||||||
|
(cfi/create-clip-index new-objects parents-index)
|
||||||
|
|
||||||
|
index
|
||||||
|
(reduce #(index-shape new-objects parents-index clip-index %1 %2)
|
||||||
|
(qdt/remove-all index changed-ids)
|
||||||
|
shapes)]
|
||||||
|
|
||||||
(assoc data :index index)))
|
(assoc data :index index)))
|
||||||
|
|
||||||
@@ -231,35 +254,36 @@
|
|||||||
(map :id))
|
(map :id))
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; PUBLIC API
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defmethod impl/handler :selection/initialize-page-index
|
(defn add-page
|
||||||
[{:keys [page] :as message}]
|
"Add a page index to the state"
|
||||||
(letfn [(add-page [state {:keys [id objects] :as page}]
|
[state {:keys [id objects] :as page}]
|
||||||
(assoc state id (create-index objects)))]
|
(assoc state id (create-index objects)))
|
||||||
(swap! state add-page page)
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(defmethod impl/handler :selection/update-page-index
|
(defn update-page
|
||||||
[{:keys [page-id old-page new-page] :as message}]
|
"Update page index on the state"
|
||||||
(swap! state update page-id
|
[state old-page new-page]
|
||||||
(fn [index]
|
(let [page-id (get old-page :id)]
|
||||||
(let [old-objects (:objects old-page)
|
(update state page-id
|
||||||
new-objects (:objects new-page)
|
(fn [index]
|
||||||
old-bounds (:bounds index)
|
(let [old-objects (:objects old-page)
|
||||||
new-bounds (objects-bounds new-objects)]
|
new-objects (:objects new-page)
|
||||||
|
old-bounds (:bounds index)
|
||||||
|
new-bounds (objects-bounds new-objects)]
|
||||||
|
|
||||||
;; If the new bounds are contained within the old bounds
|
;; If the new bounds are contained within the old bounds
|
||||||
;; we can update the index. Otherwise we need to
|
;; we can update the index. Otherwise we need to
|
||||||
;; re-create it.
|
;; re-create it.
|
||||||
(if (and (some? index)
|
(if (and (some? index)
|
||||||
(grc/contains-rect? old-bounds new-bounds))
|
(grc/contains-rect? old-bounds new-bounds))
|
||||||
(update-index index old-objects new-objects)
|
(update-index index old-objects new-objects)
|
||||||
(create-index new-objects)))))
|
(create-index new-objects)))))))
|
||||||
nil)
|
|
||||||
|
|
||||||
(defmethod impl/handler :selection/query
|
(defn query
|
||||||
[{:keys [page-id rect frame-id full-frame? include-frames? ignore-groups? clip-children? using-selrect?]
|
[index {:keys [page-id rect frame-id full-frame? include-frames? ignore-groups? clip-children? using-selrect?]
|
||||||
:or {full-frame? false include-frames? false clip-children? true using-selrect? false}
|
:or {full-frame? false include-frames? false clip-children? true using-selrect? false}}]
|
||||||
:as message}]
|
(when-let [index (get index page-id)]
|
||||||
(when-let [index (get @state page-id)]
|
|
||||||
(query-index index rect frame-id full-frame? include-frames? ignore-groups? clip-children? using-selrect?)))
|
(query-index index rect frame-id full-frame? include-frames? ignore-groups? clip-children? using-selrect?)))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
;;
|
;;
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.util.snap-data
|
(ns app.worker.snap
|
||||||
"Data structure that holds and retrieves the data to make the snaps.
|
"Data structure that holds and retrieves the data to make the snaps.
|
||||||
Internally is implemented with a balanced binary tree that queries by range.
|
Internally is implemented with a balanced binary tree that queries by range.
|
||||||
https://en.wikipedia.org/wiki/Range_tree"
|
https://en.wikipedia.org/wiki/Range_tree"
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
;;
|
|
||||||
;; Copyright (c) KALEIDOS INC
|
|
||||||
|
|
||||||
(ns app.worker.snaps
|
|
||||||
(:require
|
|
||||||
[app.common.geom.rect :as grc]
|
|
||||||
[app.util.snap-data :as sd]
|
|
||||||
[app.worker.impl :as impl]
|
|
||||||
[okulary.core :as l]))
|
|
||||||
|
|
||||||
(defonce state (l/atom {}))
|
|
||||||
|
|
||||||
;; Public API
|
|
||||||
(defmethod impl/handler :snaps/initialize-page-index
|
|
||||||
[{:keys [page] :as message}]
|
|
||||||
(swap! state sd/add-page page)
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(defmethod impl/handler :snaps/update-page-index
|
|
||||||
[{:keys [old-page new-page] :as message}]
|
|
||||||
(swap! state sd/update-page old-page new-page)
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(defmethod impl/handler :snaps/range-query
|
|
||||||
[{:keys [page-id frame-id axis ranges bounds] :as message}]
|
|
||||||
(let [match-bounds?
|
|
||||||
(fn [[_ data]]
|
|
||||||
(some #(or (= :guide (:type %))
|
|
||||||
(= :layout (:type %))
|
|
||||||
(grc/contains-point? bounds (:pt %))) data))]
|
|
||||||
(->> (into []
|
|
||||||
(comp (mapcat #(sd/query @state page-id frame-id axis %))
|
|
||||||
(distinct))
|
|
||||||
ranges)
|
|
||||||
(filter match-bounds?))))
|
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
[frontend-tests.tokens.token-form-test]
|
[frontend-tests.tokens.token-form-test]
|
||||||
[frontend-tests.util-range-tree-test]
|
[frontend-tests.util-range-tree-test]
|
||||||
[frontend-tests.util-simple-math-test]
|
[frontend-tests.util-simple-math-test]
|
||||||
[frontend-tests.util-snap-data-test]))
|
[frontend-tests.worker-snap-test]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@
|
|||||||
(defn init
|
(defn init
|
||||||
[]
|
[]
|
||||||
(t/run-tests
|
(t/run-tests
|
||||||
|
'frontend-tests.basic-shapes-test
|
||||||
|
'frontend-tests.data.workspace-colors-test
|
||||||
'frontend-tests.helpers-shapes-test
|
'frontend-tests.helpers-shapes-test
|
||||||
'frontend-tests.logic.comp-remove-swap-slots-test
|
'frontend-tests.logic.comp-remove-swap-slots-test
|
||||||
'frontend-tests.logic.components-and-tokens
|
'frontend-tests.logic.components-and-tokens
|
||||||
@@ -38,13 +40,11 @@
|
|||||||
'frontend-tests.logic.groups-test
|
'frontend-tests.logic.groups-test
|
||||||
'frontend-tests.logic.pasting-in-containers-test
|
'frontend-tests.logic.pasting-in-containers-test
|
||||||
'frontend-tests.plugins.context-shapes-test
|
'frontend-tests.plugins.context-shapes-test
|
||||||
'frontend-tests.util-range-tree-test
|
'frontend-tests.tokens.import-export-test
|
||||||
'frontend-tests.util-snap-data-test
|
|
||||||
'frontend-tests.util-simple-math-test
|
|
||||||
'frontend-tests.basic-shapes-test
|
|
||||||
'frontend-tests.data.workspace-colors-test
|
|
||||||
'frontend-tests.tokens.logic.token-actions-test
|
'frontend-tests.tokens.logic.token-actions-test
|
||||||
'frontend-tests.tokens.logic.token-data-test
|
'frontend-tests.tokens.logic.token-data-test
|
||||||
'frontend-tests.tokens.import-export-test
|
|
||||||
'frontend-tests.tokens.style-dictionary-test
|
'frontend-tests.tokens.style-dictionary-test
|
||||||
'frontend-tests.tokens.token-form-test))
|
'frontend-tests.tokens.token-form-test
|
||||||
|
'frontend-tests.util-range-tree-test
|
||||||
|
'frontend-tests.util-simple-math-test
|
||||||
|
'frontend-tests.worker-snap-test))
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
;;
|
;;
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns frontend-tests.util-snap-data-test
|
(ns frontend-tests.worker-snap-test
|
||||||
(:require
|
(:require
|
||||||
[app.common.files.builder :as fb]
|
[app.common.files.builder :as fb]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.snap-data :as sd]
|
[app.worker.snap :as snap]
|
||||||
[cljs.pprint :refer [pprint]]
|
[cljs.pprint :refer [pprint]]
|
||||||
[cljs.test :as t :include-macros true]))
|
[cljs.test :as t :include-macros true]))
|
||||||
|
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(uuid/custom 123456789 (swap! counter inc)))))
|
(uuid/custom 123456789 (swap! counter inc)))))
|
||||||
|
|
||||||
(t/deftest test-create-index
|
(t/deftest create-index
|
||||||
(t/testing "Create empty data"
|
(t/testing "Create empty data"
|
||||||
(let [data (sd/make-snap-data)]
|
(let [data (snap/make-snap-data)]
|
||||||
(t/is (some? data))))
|
(t/is (some? data))))
|
||||||
|
|
||||||
(t/testing "Add empty page (only root-frame)"
|
(t/testing "Add empty page (only root-frame)"
|
||||||
@@ -32,8 +32,8 @@
|
|||||||
(fb/add-page {:name "Page 1"})
|
(fb/add-page {:name "Page 1"})
|
||||||
(fb/get-current-page))
|
(fb/get-current-page))
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))]
|
(snap/add-page page))]
|
||||||
(t/is (some? data))))
|
(t/is (some? data))))
|
||||||
|
|
||||||
(t/testing "Create simple shape on root"
|
(t/testing "Create simple shape on root"
|
||||||
@@ -48,10 +48,10 @@
|
|||||||
:height 100}))
|
:height 100}))
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
result-x (sd/query data (:id page) uuid/zero :x [0 100])]
|
result-x (snap/query data (:id page) uuid/zero :x [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@
|
|||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
;; frame-id (::fb/last-id file)
|
;; frame-id (::fb/last-id file)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])]
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-zero-x) 3))
|
(t/is (= (count result-zero-x) 3))
|
||||||
@@ -116,11 +116,11 @@
|
|||||||
|
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])]
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-zero-x) 3))
|
(t/is (= (count result-zero-x) 3))
|
||||||
@@ -137,13 +137,13 @@
|
|||||||
frame-id (::fb/last-id state)
|
frame-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-y (sd/query data (:id page) uuid/zero :y [0 100])
|
result-zero-y (snap/query data (:id page) uuid/zero :y [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-frame-y (sd/query data (:id page) frame-id :y [0 100])]
|
result-frame-y (snap/query data (:id page) frame-id :y [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
;; We can snap in the root
|
;; We can snap in the root
|
||||||
@@ -168,13 +168,13 @@
|
|||||||
|
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-y (sd/query data (:id page) uuid/zero :y [0 100])
|
result-zero-y (snap/query data (:id page) uuid/zero :y [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-frame-y (sd/query data (:id page) frame-id :y [0 100])]
|
result-frame-y (snap/query data (:id page) frame-id :y [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
;; We can snap in the root
|
;; We can snap in the root
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
(t/is (= (count result-frame-x) 1))
|
(t/is (= (count result-frame-x) 1))
|
||||||
(t/is (= (count result-frame-y) 0)))))
|
(t/is (= (count result-frame-y) 0)))))
|
||||||
|
|
||||||
(t/deftest test-update-index
|
(t/deftest update-index
|
||||||
(t/testing "Create frame on root and then remove it."
|
(t/testing "Create frame on root and then remove it."
|
||||||
(let [state (-> (fb/create-state)
|
(let [state (-> (fb/create-state)
|
||||||
(fb/add-file {:name "Test"})
|
(fb/add-file {:name "Test"})
|
||||||
@@ -200,17 +200,17 @@
|
|||||||
shape-id (::fb/last-id state)
|
shape-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
state (-> state
|
state (-> state
|
||||||
(fb/delete-shape shape-id))
|
(fb/delete-shape shape-id))
|
||||||
|
|
||||||
new-page (fb/get-current-page state)
|
new-page (fb/get-current-page state)
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-y (sd/query data (:id page) uuid/zero :y [0 100])]
|
result-y (snap/query data (:id page) uuid/zero :y [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-x) 0))
|
(t/is (= (count result-x) 0))
|
||||||
@@ -231,16 +231,16 @@
|
|||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
|
|
||||||
;; frame-id (::fb/last-id state)
|
;; frame-id (::fb/last-id state)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
state (fb/delete-shape state shape-id)
|
state (fb/delete-shape state shape-id)
|
||||||
|
|
||||||
new-page (fb/get-current-page state)
|
new-page (fb/get-current-page state)
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-y (sd/query data (:id page) uuid/zero :y [0 100])]
|
result-y (snap/query data (:id page) uuid/zero :y [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-x) 0))
|
(t/is (= (count result-x) 0))
|
||||||
@@ -263,16 +263,16 @@
|
|||||||
state (fb/close-board state)
|
state (fb/close-board state)
|
||||||
|
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
state (fb/delete-shape state shape-id)
|
state (fb/delete-shape state shape-id)
|
||||||
new-page (fb/get-current-page state)
|
new-page (fb/get-current-page state)
|
||||||
|
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])]
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-zero-x) 3))
|
(t/is (= (count result-zero-x) 3))
|
||||||
@@ -291,18 +291,18 @@
|
|||||||
|
|
||||||
frame-id (::fb/last-id state)
|
frame-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
new-page (-> (fb/delete-guide state guide-id)
|
new-page (-> (fb/delete-guide state guide-id)
|
||||||
(fb/get-current-page))
|
(fb/get-current-page))
|
||||||
|
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-y (sd/query data (:id page) uuid/zero :y [0 100])
|
result-zero-y (snap/query data (:id page) uuid/zero :y [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-frame-y (sd/query data (:id page) frame-id :y [0 100])]
|
result-frame-y (snap/query data (:id page) frame-id :y [0 100])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
;; We can snap in the root
|
;; We can snap in the root
|
||||||
@@ -325,17 +325,17 @@
|
|||||||
guide-id (::fb/last-id file)
|
guide-id (::fb/last-id file)
|
||||||
|
|
||||||
page (fb/get-current-page file)
|
page (fb/get-current-page file)
|
||||||
data (-> (sd/make-snap-data) (sd/add-page page))
|
data (-> (snap/make-snap-data) (snap/add-page page))
|
||||||
|
|
||||||
new-page (-> (fb/delete-guide file guide-id)
|
new-page (-> (fb/delete-guide file guide-id)
|
||||||
(fb/get-current-page))
|
(fb/get-current-page))
|
||||||
|
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-y (sd/query data (:id page) uuid/zero :y [0 100])
|
result-zero-y (snap/query data (:id page) uuid/zero :y [0 100])
|
||||||
result-frame-x (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-frame-y (sd/query data (:id page) frame-id :y [0 100])]
|
result-frame-y (snap/query data (:id page) frame-id :y [0 100])]
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
;; We can snap in the root
|
;; We can snap in the root
|
||||||
(t/is (= (count result-zero-x) 0))
|
(t/is (= (count result-zero-x) 0))
|
||||||
@@ -358,8 +358,8 @@
|
|||||||
|
|
||||||
frame-id (::fb/last-id state)
|
frame-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
state (fb/update-shape state frame-id
|
state (fb/update-shape state frame-id
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
@@ -370,12 +370,12 @@
|
|||||||
|
|
||||||
|
|
||||||
new-page (fb/get-current-page state)
|
new-page (fb/get-current-page state)
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x-1 (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x-1 (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-frame-x-1 (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x-1 (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-zero-x-2 (sd/query data (:id page) uuid/zero :x [200 300])
|
result-zero-x-2 (snap/query data (:id page) uuid/zero :x [200 300])
|
||||||
result-frame-x-2 (sd/query data (:id page) frame-id :x [200 300])]
|
result-frame-x-2 (snap/query data (:id page) frame-id :x [200 300])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-zero-x-1) 0))
|
(t/is (= (count result-zero-x-1) 0))
|
||||||
@@ -396,8 +396,8 @@
|
|||||||
|
|
||||||
shape-id (::fb/last-id state)
|
shape-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
data (-> (sd/make-snap-data)
|
data (-> (snap/make-snap-data)
|
||||||
(sd/add-page page))
|
(snap/add-page page))
|
||||||
|
|
||||||
state (fb/update-shape state shape-id
|
state (fb/update-shape state shape-id
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
@@ -408,10 +408,10 @@
|
|||||||
|
|
||||||
new-page (fb/get-current-page state)
|
new-page (fb/get-current-page state)
|
||||||
;; FIXME: update
|
;; FIXME: update
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x-1 (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x-1 (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-x-2 (sd/query data (:id page) uuid/zero :x [200 300])]
|
result-zero-x-2 (snap/query data (:id page) uuid/zero :x [200 300])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
(t/is (= (count result-zero-x-1) 0))
|
(t/is (= (count result-zero-x-1) 0))
|
||||||
@@ -432,22 +432,22 @@
|
|||||||
|
|
||||||
frame-id (::fb/last-id state)
|
frame-id (::fb/last-id state)
|
||||||
page (fb/get-current-page state)
|
page (fb/get-current-page state)
|
||||||
data (-> (sd/make-snap-data) (sd/add-page page))
|
data (-> (snap/make-snap-data) (snap/add-page page))
|
||||||
|
|
||||||
new-page (-> (fb/update-guide state (assoc guide :position 150))
|
new-page (-> (fb/update-guide state (assoc guide :position 150))
|
||||||
(fb/get-current-page))
|
(fb/get-current-page))
|
||||||
|
|
||||||
data (sd/update-page data page new-page)
|
data (snap/update-page data page new-page)
|
||||||
|
|
||||||
result-zero-x-1 (sd/query data (:id page) uuid/zero :x [0 100])
|
result-zero-x-1 (snap/query data (:id page) uuid/zero :x [0 100])
|
||||||
result-zero-y-1 (sd/query data (:id page) uuid/zero :y [0 100])
|
result-zero-y-1 (snap/query data (:id page) uuid/zero :y [0 100])
|
||||||
result-frame-x-1 (sd/query data (:id page) frame-id :x [0 100])
|
result-frame-x-1 (snap/query data (:id page) frame-id :x [0 100])
|
||||||
result-frame-y-1 (sd/query data (:id page) frame-id :y [0 100])
|
result-frame-y-1 (snap/query data (:id page) frame-id :y [0 100])
|
||||||
|
|
||||||
result-zero-x-2 (sd/query data (:id page) uuid/zero :x [0 200])
|
result-zero-x-2 (snap/query data (:id page) uuid/zero :x [0 200])
|
||||||
result-zero-y-2 (sd/query data (:id page) uuid/zero :y [0 200])
|
result-zero-y-2 (snap/query data (:id page) uuid/zero :y [0 200])
|
||||||
result-frame-x-2 (sd/query data (:id page) frame-id :x [0 200])
|
result-frame-x-2 (snap/query data (:id page) frame-id :x [0 200])
|
||||||
result-frame-y-2 (sd/query data (:id page) frame-id :y [0 200])]
|
result-frame-y-2 (snap/query data (:id page) frame-id :y [0 200])]
|
||||||
|
|
||||||
(t/is (some? data))
|
(t/is (some? data))
|
||||||
|
|
||||||
Reference in New Issue
Block a user