Skip to content

Commit 5b798a3

Browse files
authored
Merge pull request #66 from MawiraIke/fix/path-generation
Path generation performance improvements
2 parents e20861f + 75eb0f6 commit 5b798a3

File tree

2 files changed

+49
-29
lines changed

2 files changed

+49
-29
lines changed

src/lib/devtools/formatters/printing.cljs

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@
119119

120120
(defn alt-printer-impl [obj writer opts]
121121
(binding [*current-state* (get-current-state)]
122-
(add-object-to-current-path-info! obj)
122+
(when (pref :render-path-annotations)
123+
(add-object-to-current-path-info! obj))
123124
(let [{:keys [markup-db]} opts
124125
circular? (is-circular? obj)
125126
inner-writer (make-template-writer (:markup-db opts))

src/lib/devtools/formatters/state.cljs

+47-28
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@
5757
(number? v) v
5858
:else "?"))
5959

60-
(defn seek-path-segment [coll val]
60+
(defn seek-path-segment [coll val & [seq'd-map?]]
6161
(let [* (fn [[k v]]
6262
(cond
6363
;; we need to know the paths for keywords, these are clickable
64-
(identical? k val)
64+
(and seq'd-map? (identical? k val))
6565
(present-path-segment k)
6666

6767
(identical? v val)
@@ -70,8 +70,15 @@
7070

7171
(defn build-path-segment [parent-object object]
7272
(cond
73-
(map? parent-object) (seek-path-segment (seq parent-object) object)
74-
(sequential? parent-object) (seek-path-segment (map-indexed (fn [i x] [i x]) parent-object) object)))
73+
(map? parent-object) (seek-path-segment (seq parent-object) object true)
74+
(sequential? parent-object) (seek-path-segment (map-indexed (fn [i x] [i x]) parent-object) object)
75+
(and (set? parent-object)
76+
(contains? parent-object object)
77+
(or (string? object)
78+
(keyword? object)
79+
(integer? object))) object ;; if set has the simple object, return the object instead.
80+
(and (set? parent-object) ;; in composite objects in sets, return the index in the set.
81+
(contains? parent-object object)) (seek-path-segment (map-indexed (fn [i x] [i x]) parent-object) object)))
7582

7683
;; This function checks a unique situation of looping an immediate child element `obj` of a parent element `history`
7784
;; say we have a general map {:a 2 :b {:gh 45} :c 4}
@@ -85,33 +92,45 @@
8592
;; get the first item in the vector which is the path.
8693
(defn mapping?
8794
[history obj]
88-
(let [obj-kw (when (and (vector? obj)
89-
(= (count obj) 2)
90-
;; the map keys must always be one of these
91-
(or
92-
(-> obj first keyword?)
93-
(-> obj first string?)
94-
(-> obj first number?)))
95-
(first obj))]
96-
(when (and (map? history) obj-kw)
97-
(contains? history obj-kw))))
95+
(let [first-kw (when (and (vector? obj)
96+
(map? history))
97+
(nth obj 0 nil))
98+
valid-kw? (and first-kw
99+
(or (keyword? first-kw)
100+
(string? first-kw)
101+
(number? first-kw))
102+
;; intentionally delaying realizing the whole vector
103+
(= (count obj) 2))]
104+
(when valid-kw?
105+
(contains? history first-kw))))
106+
107+
(defn ignore-path-in-fake-vector
108+
[history obj path]
109+
;; if the current item we are looping at is an artificial vector (explained at `mapping` above),
110+
;; don't append to the path
111+
(when (mapping? history obj)
112+
(or path [])))
113+
114+
(defn find-path-in-fake-vector
115+
[history path]
116+
(let [second-last-history (get-second-last-object-from-current-history)]
117+
;; if the previous item is an artificial vector, lets append to the path info but take the first item
118+
;; in the artificial vector as the path. (Explained in `mapping` above)
119+
(when (mapping? second-last-history history)
120+
(conj (or path []) (nth history 0 nil)))))
121+
122+
(defn find-path
123+
[history obj path]
124+
(let [path-segment (build-path-segment history obj)]
125+
(when (some? path-segment)
126+
(conj (or path []) path-segment))))
98127

99128
(defn extend-path-info [path-info object]
100129
(let [parent-object (get-last-object-from-current-history)]
101-
(cond
102-
;; if the current item we are looping at is an artificial vector (explained at `mapping` above),
103-
;; dont append to the path
104-
(and (map? parent-object) (mapping? parent-object object))
105-
path-info
106-
;; if the previous item is an artificial vector, lets append to the path info but take the first item
107-
;; in the vector as the path. (Explained in `mapping` above)
108-
(and (map? (get-second-last-object-from-current-history))
109-
(mapping? (get-second-last-object-from-current-history) parent-object))
110-
(conj (or path-info []) (first parent-object))
111-
;; the current object is an item within the parent object
112-
(some? (build-path-segment parent-object object))
113-
(conj (or path-info []) (build-path-segment parent-object object))
114-
:else path-info)))
130+
(or (ignore-path-in-fake-vector parent-object object path-info)
131+
(find-path-in-fake-vector parent-object path-info)
132+
(find-path parent-object object path-info)
133+
path-info)))
115134

116135
(defn add-object-to-current-path-info! [object]
117136
(update-current-state! update :path-info extend-path-info object))

0 commit comments

Comments
 (0)