🔧 Small refactor changes-builder

This commit is contained in:
Andrés Moya 2022-02-21 17:14:54 +01:00
parent 96870c3fee
commit 8682c07148
2 changed files with 71 additions and 77 deletions

View file

@ -31,46 +31,69 @@
(defn with-objects [changes objects] (defn with-objects [changes objects]
(vary-meta changes assoc ::objects objects)) (vary-meta changes assoc ::objects objects))
(defn amend-last-change
"Modify the last redo-changes added with an update function."
[changes f]
(update changes :redo-changes
#(conj (pop %) (f (peek %)))))
(defn amend-changes
"Modify all redo-changes with an update function."
[changes f]
(update changes :redo-changes #(mapv f %)))
(defn- assert-page-id
[changes]
(assert (contains? (meta changes) ::page-id) "Give a page-id or call (with-page) before using this function"))
(defn- assert-page
[changes]
(assert (contains? (meta changes) ::page) "Call (with-page) before using this function"))
(defn- assert-objects
[changes]
(assert (contains? (meta changes) ::objects) "Call (with-objects) before using this function"))
;; Page changes ;; Page changes
(defn add-empty-page (defn add-empty-page
[chdata id name] [changes id name]
(-> chdata (-> changes
(update :redo-changes conj {:type :add-page :id id :name name}) (update :redo-changes conj {:type :add-page :id id :name name})
(update :undo-changes conj {:type :del-page :id id}))) (update :undo-changes conj {:type :del-page :id id})))
(defn add-page (defn add-page
[chdata id page] [changes id page]
(-> chdata (-> changes
(update :redo-changes conj {:type :add-page :id id :page page}) (update :redo-changes conj {:type :add-page :id id :page page})
(update :undo-changes conj {:type :del-page :id id}))) (update :undo-changes conj {:type :del-page :id id})))
(defn mod-page (defn mod-page
[chdata page new-name] [changes page new-name]
(-> chdata (-> changes
(update :redo-changes conj {:type :mod-page :id (:id page) :name new-name}) (update :redo-changes conj {:type :mod-page :id (:id page) :name new-name})
(update :undo-changes conj {:type :mod-page :id (:id page) :name (:name page)}))) (update :undo-changes conj {:type :mod-page :id (:id page) :name (:name page)})))
(defn del-page (defn del-page
[chdata page] [changes page]
(-> chdata (-> changes
(update :redo-changes conj {:type :del-page :id (:id page)}) (update :redo-changes conj {:type :del-page :id (:id page)})
(update :undo-changes conj {:type :add-page :id (:id page) :page page}))) (update :undo-changes conj {:type :add-page :id (:id page) :page page})))
(defn move-page (defn move-page
[chdata index prev-index] [changes page-id index prev-index]
(let [page-id (::page-id (meta chdata))] (-> changes
(-> chdata (update :redo-changes conj {:type :mov-page :id page-id :index index})
(update :redo-changes conj {:type :mov-page :id page-id :index index}) (update :undo-changes conj {:type :mov-page :id page-id :index prev-index})))
(update :undo-changes conj {:type :mov-page :id page-id :index prev-index}))))
(defn set-page-option (defn set-page-option
[chdata option-key option-val] [changes option-key option-val]
(let [page-id (::page-id (meta chdata)) (assert-page changes)
page (::page (meta chdata)) (let [page-id (::page-id (meta changes))
page (::page (meta changes))
old-val (get-in page [:options option-key])] old-val (get-in page [:options option-key])]
(-> chdata (-> changes
(update :redo-changes conj {:type :set-option (update :redo-changes conj {:type :set-option
:page-id page-id :page-id page-id
:option option-key :option option-key
@ -87,6 +110,7 @@
(add-obj changes obj nil)) (add-obj changes obj nil))
([changes obj {:keys [index ignore-touched] :or {index ::undefined ignore-touched false}}] ([changes obj {:keys [index ignore-touched] :or {index ::undefined ignore-touched false}}]
(assert-page-id changes)
(let [obj (cond-> obj (let [obj (cond-> obj
(not= index ::undefined) (not= index ::undefined)
(assoc :index index)) (assoc :index index))
@ -111,10 +135,12 @@
(update :undo-changes d/preconj del-change))))) (update :undo-changes d/preconj del-change)))))
(defn change-parent (defn change-parent
([changes parent-id shapes] (change-parent changes parent-id shapes nil)) ([changes parent-id shapes]
([changes parent-id shapes index] (change-parent changes parent-id shapes nil))
(assert (contains? (meta changes) ::objects) "Call (with-objects) first to use this function")
([changes parent-id shapes index]
(assert-page-id changes)
(assert-objects changes)
(let [objects (::objects (meta changes)) (let [objects (::objects (meta changes))
set-parent-change set-parent-change
(cond-> {:type :mov-objects (cond-> {:type :mov-objects
@ -139,18 +165,6 @@
(update :redo-changes conj set-parent-change) (update :redo-changes conj set-parent-change)
(update :undo-changes #(reduce mk-undo-change % shapes)))))) (update :undo-changes #(reduce mk-undo-change % shapes))))))
(defn- generate-operation
"Given an object old and new versions and an attribute will append into changes
the set and undo operations"
[changes attr old new ignore-geometry?]
(let [old-val (get old attr)
new-val (get new attr)]
(if (= old-val new-val)
changes
(-> changes
(update :rops conj {:type :set :attr attr :val new-val :ignore-geometry ignore-geometry?})
(update :uops conj {:type :set :attr attr :val old-val :ignore-touched true})))))
(defn update-shapes (defn update-shapes
"Calculate the changes and undos to be done when a function is applied to a "Calculate the changes and undos to be done when a function is applied to a
single object" single object"
@ -158,9 +172,20 @@
(update-shapes changes ids update-fn nil)) (update-shapes changes ids update-fn nil))
([changes ids update-fn {:keys [attrs ignore-geometry?] :or {attrs nil ignore-geometry? false}}] ([changes ids update-fn {:keys [attrs ignore-geometry?] :or {attrs nil ignore-geometry? false}}]
(assert (contains? (meta changes) ::objects) "Call (with-objects) first to use this function") (assert-page-id changes)
(assert-objects changes)
(let [objects (::objects (meta changes)) (let [objects (::objects (meta changes))
generate-operation
(fn [changes attr old new ignore-geometry?]
(let [old-val (get old attr)
new-val (get new attr)]
(if (= old-val new-val)
changes
(-> changes
(update :rops conj {:type :set :attr attr :val new-val :ignore-geometry ignore-geometry?})
(update :uops conj {:type :set :attr attr :val old-val :ignore-touched true})))))
update-shape update-shape
(fn [changes id] (fn [changes id]
(let [old-obj (get objects id) (let [old-obj (get objects id)
@ -192,7 +217,8 @@
(defn remove-objects (defn remove-objects
[changes ids] [changes ids]
(assert (contains? (meta changes) ::objects) "Call (with-objects) first to use this function") (assert-page-id changes)
(assert-objects changes)
(let [page-id (::page-id (meta changes)) (let [page-id (::page-id (meta changes))
objects (::objects (meta changes)) objects (::objects (meta changes))
@ -235,44 +261,12 @@
(reduce add-undo-change-parent $ ids) (reduce add-undo-change-parent $ ids)
(reduce add-undo-change-shape $ ids)))))) (reduce add-undo-change-shape $ ids))))))
(defn move-page (defn resize-parents
[chdata index prev-index] [changes ids]
(let [page-id (::page-id (meta chdata))] (assert-page-id changes)
(-> chdata (let [page-id (::page-id (meta changes))
(update :redo-changes conj {:type :mov-page :id page-id :index index}) shapes (vec ids)]
(update :undo-changes conj {:type :mov-page :id page-id :index prev-index})))) (-> changes
(update :redo-changes conj {:type :reg-objects :page-id page-id :shapes shapes})
(defn set-page-option (update :undo-changes conj {:type :reg-objects :page-id page-id :shapes shapes}))))
[chdata option-key option-val]
(let [page-id (::page-id (meta chdata))
page (::page (meta chdata))
old-val (get-in page [:options option-key])]
(-> chdata
(update :redo-changes conj {:type :set-option
:page-id page-id
:option option-key
:value option-val})
(update :undo-changes conj {:type :set-option
:page-id page-id
:option option-key
:value old-val}))))
(defn reg-objects
[chdata shape-ids]
(let [page-id (::page-id (meta chdata))]
(-> chdata
(update :redo-changes conj {:type :reg-objects :page-id page-id :shapes shape-ids}))))
;; No need to do anything to undo
(defn amend-last-change
"Modify the last redo-changes added with an update function."
[chdata f]
(update chdata :redo-changes
#(conj (pop %) (f (peek %)))))
(defn amend-changes
"Modify all redo-changes with an update function."
[chdata f]
(update chdata :redo-changes #(mapv f %)))

View file

@ -1163,8 +1163,8 @@
(watch [it state _] (watch [it state _]
(let [prev-index (-> (get-in state [:workspace-data :pages]) (let [prev-index (-> (get-in state [:workspace-data :pages])
(d/index-of id)) (d/index-of id))
changes (-> (pcb/empty-changes it id) changes (-> (pcb/empty-changes it)
(pcb/move-page index prev-index))] (pcb/move-page id index prev-index))]
(rx/of (dch/commit-changes changes)))))) (rx/of (dch/commit-changes changes))))))
;; --- Shape / Selection Alignment and Distribution ;; --- Shape / Selection Alignment and Distribution
@ -1837,7 +1837,7 @@
;; Adds a reg-objects operation so the groups are updated. We add all the new objects ;; Adds a reg-objects operation so the groups are updated. We add all the new objects
new-objects-ids (->> changes :redo-changes (filter #(= (:type %) :add-obj)) (mapv :id)) new-objects-ids (->> changes :redo-changes (filter #(= (:type %) :add-obj)) (mapv :id))
changes (pcb/reg-objects changes new-objects-ids) changes (pcb/resize-parents changes new-objects-ids)
selected (->> changes selected (->> changes
:redo-changes :redo-changes