diff --git a/frontend/src/app/main.cljs b/frontend/src/app/main.cljs index 04b6a00f4..1339369b1 100644 --- a/frontend/src/app/main.cljs +++ b/frontend/src/app/main.cljs @@ -23,6 +23,7 @@ [app.util.i18n :as i18n] [app.util.theme :as theme] [beicon.core :as rx] + [debug] [potok.core :as ptk] [rumext.alpha :as mf])) diff --git a/frontend/src/app/main/store.cljs b/frontend/src/app/main/store.cljs index 78a93c1a8..ab234196d 100644 --- a/frontend/src/app/main/store.cljs +++ b/frontend/src/app/main/store.cljs @@ -7,11 +7,7 @@ (ns app.main.store (:require-macros [app.main.store]) (:require - [app.common.data :as d] - [app.common.pages :as cp] - [app.util.debug :refer [debug? debug-exclude-events logjs]] [beicon.core :as rx] - [cuerdas.core :as str] [okulary.core :as l] [potok.core :as ptk])) @@ -42,14 +38,6 @@ buffer)) -(when *assert* - (defonce debug-subscription - (->> stream - (rx/filter ptk/event?) - (rx/filter (fn [s] (and (debug? :events) - (not (debug-exclude-events (ptk/type s)))))) - (rx/subs #(println "[stream]: " (ptk/repr-event %)))))) - (defn emit! ([] nil) ([event] @@ -63,99 +51,4 @@ [& events] #(apply ptk/emit! state events)) -(defn ^:export dump-state [] - (logjs "state" @state)) - -(defn ^:export dump-buffer [] - (logjs "state" @last-events)) - -(defn ^:export get-state [str-path] - (let [path (->> (str/split str-path " ") - (map d/read-string))] - (clj->js (get-in @state path)))) - -(defn ^:export dump-objects [] - (let [page-id (get @state :current-page-id)] - (logjs "state" (get-in @state [:workspace-data :pages-index page-id :objects])))) - -(defn ^:export dump-object [name] - (let [page-id (get @state :current-page-id) - objects (get-in @state [:workspace-data :pages-index page-id :objects]) - target (or (d/seek (fn [[_ shape]] (= name (:name shape))) objects) - (get objects (uuid name)))] - (->> target - (logjs "state")))) - -(defn ^:export dump-tree - ([] (dump-tree false false)) - ([show-ids] (dump-tree show-ids false)) - ([show-ids show-touched] - (let [page-id (get @state :current-page-id) - objects (get-in @state [:workspace-data :pages-index page-id :objects]) - components (get-in @state [:workspace-data :components]) - libraries (get @state :workspace-libraries) - root (d/seek #(nil? (:parent-id %)) (vals objects))] - - (letfn [(show-shape [shape-id level objects] - (let [shape (get objects shape-id)] - (println (str/pad (str (str/repeat " " level) - (:name shape) - (when (seq (:touched shape)) "*") - (when show-ids (str/format " <%s>" (:id shape)))) - {:length 20 - :type :right}) - (show-component shape objects)) - (when show-touched - (when (seq (:touched shape)) - (println (str (str/repeat " " level) - " " - (str (:touched shape))))) - (when (:remote-synced? shape) - (println (str (str/repeat " " level) - " (remote-synced)")))) - (when (:shapes shape) - (dorun (for [shape-id (:shapes shape)] - (show-shape shape-id (inc level) objects)))))) - - (show-component [shape objects] - (if (nil? (:shape-ref shape)) - "" - (let [root-shape (cp/get-component-shape shape objects) - component-id (when root-shape (:component-id root-shape)) - component-file-id (when root-shape (:component-file root-shape)) - component-file (when component-file-id (get libraries component-file-id nil)) - component (when component-id - (if component-file - (get-in component-file [:data :components component-id]) - (get components component-id))) - component-shape (when (and component (:shape-ref shape)) - (get-in component [:objects (:shape-ref shape)]))] - (str/format " %s--> %s%s%s" - (cond (:component-root? shape) "#" - (:component-id shape) "@" - :else "-") - (when component-file (str/format "<%s> " (:name component-file))) - (or (:name component-shape) "?") - (if (or (:component-root? shape) - (nil? (:component-id shape)) - true) - "" - (let [component-id (:component-id shape) - component-file-id (:component-file shape) - component-file (when component-file-id (get libraries component-file-id nil)) - component (if component-file - (get-in component-file [:data :components component-id]) - (get components component-id))] - (str/format " (%s%s)" - (when component-file (str/format "<%s> " (:name component-file))) - (:name component))))))))] - - (println "[Page]") - (show-shape (:id root) 0 objects) - - (dorun (for [component (vals components)] - (do - (println) - (println (str/format "[%s]" (:name component))) - (show-shape (:id component) 0 (:objects component))))))))) diff --git a/frontend/src/app/main/ui/workspace/shapes.cljs b/frontend/src/app/main/ui/workspace/shapes.cljs index 70efd1f49..2a260de3c 100644 --- a/frontend/src/app/main/ui/workspace/shapes.cljs +++ b/frontend/src/app/main/ui/workspace/shapes.cljs @@ -28,8 +28,8 @@ [app.main.ui.workspace.shapes.path :as path] [app.main.ui.workspace.shapes.svg-raw :as svg-raw] [app.main.ui.workspace.shapes.text :as text] - [app.util.debug :refer [debug?]] [app.util.object :as obj] + [debug :refer [debug?]] [okulary.core :as l] [rumext.alpha :as mf])) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index 380dac1c7..7a842c39b 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -14,6 +14,7 @@ [app.util.object :as obj] [app.util.timers :as ts] [beicon.core :as rx] + [debug :refer [debug?]] [rumext.alpha :as mf])) (defn check-frame-props @@ -47,8 +48,7 @@ :width (:width shape) :height (:height shape) ;; DEBUG - ;; :style {:filter "sepia(1)"} - }]))) + :style {:filter (when (debug? :thumbnails) "sepia(1)")}}]))) ;; This custom deferred don't defer rendering when ghost rendering is ;; used. diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 1f3bf6690..71a5c1d80 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -15,10 +15,10 @@ [app.main.store :as st] [app.main.ui.cursors :as cur] [app.main.ui.workspace.shapes.path.editor :refer [path-editor]] - [app.util.debug :refer [debug?]] [app.util.dom :as dom] [app.util.object :as obj] [cuerdas.core :as str] + [debug :refer [debug?]] [rumext.alpha :as mf] [rumext.util :refer [map->obj]])) diff --git a/frontend/src/app/util/debug.cljs b/frontend/src/app/util/debug.cljs deleted file mode 100644 index c3ee88d9f..000000000 --- a/frontend/src/app/util/debug.cljs +++ /dev/null @@ -1,95 +0,0 @@ -(ns app.util.debug - "Debugging utils" - (:require - [app.common.math :as mth] - [app.util.object :as obj] - [app.util.timers :as timers] - [cljs.pprint :refer [pprint]])) - -(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center :export :import #_:simple-selection}) - -;; These events are excluded when we activate the :events flag -(def debug-exclude-events - #{:app.main.data.workspace.notifications/handle-pointer-update - :app.main.data.workspace.selection/change-hover-state}) - -(defonce ^:dynamic *debug* (atom #{#_:events})) - -(defn debug-all! [] (reset! *debug* debug-options)) -(defn debug-none! [] (reset! *debug* #{})) -(defn debug! [option] (swap! *debug* conj option)) -(defn -debug! [option] (swap! *debug* disj option)) - -(defn ^:export ^boolean debug? - [option] - (if *assert* - (boolean (@*debug* option)) - false)) - -(defn ^:export toggle-debug [name] (let [option (keyword name)] - (if (debug? option) - (-debug! option) - (debug! option)))) -(defn ^:export debug-all [] (debug-all!)) -(defn ^:export debug-none [] (debug-none!)) - -(defn ^:export tap - "Transducer function that can execute a side-effect `effect-fn` per input" - [effect-fn] - - (fn [rf] - (fn - ([] (rf)) - ([result] (rf result)) - ([result input] - (effect-fn input) - (rf result input))))) - -(defn ^:export logjs - ([str] (tap (partial logjs str))) - ([str val] - (js/console.log str (clj->js val)) - val)) - -(when (exists? js/window) - (set! (.-dbg ^js js/window) clj->js) - (set! (.-pp ^js js/window) pprint)) - - -(defonce widget-style " - background: black; - bottom: 10px; - color: white; - height: 20px; - padding-left: 8px; - position: absolute; - right: 10px; - width: 40px; - z-index: 99999; - opacity: 0.5; -") - -(defn ^:export fps - "Adds a widget to keep track of the average FPS's" - [] - (let [last (volatile! (.now js/performance)) - avg (volatile! 0) - node (-> (.createElement js/document "div") - (obj/set! "id" "fps") - (obj/set! "style" widget-style)) - body (obj/get js/document "body") - - do-thing (fn do-thing [] - (timers/raf - (fn [] - (let [cur (.now js/performance) - ts (/ 1000 (* (- cur @last))) - val (+ @avg (* (- ts @avg) 0.1))] - - (obj/set! node "innerText" (mth/precision val 0)) - (vreset! last cur) - (vreset! avg val) - (do-thing)))))] - - (.appendChild body node) - (do-thing))) diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs new file mode 100644 index 000000000..2f6d65561 --- /dev/null +++ b/frontend/src/debug.cljs @@ -0,0 +1,211 @@ +;; 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) UXBOX Labs SL + +(ns debug + (:require + [app.common.data :as d] + [app.common.math :as mth] + [app.common.pages :as cp] + [app.main.store :as st] + [app.util.object :as obj] + [app.util.timers :as timers] + [beicon.core :as rx] + [cljs.pprint :refer [pprint]] + [cuerdas.core :as str] + [potok.core :as ptk])) + +(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center :export :import #_:simple-selection}) + +;; These events are excluded when we activate the :events flag +(def debug-exclude-events + #{:app.main.data.workspace.notifications/handle-pointer-update + :app.main.data.workspace.selection/change-hover-state}) + +(defonce ^:dynamic *debug* (atom #{#_:events})) + +(defn debug-all! [] (reset! *debug* debug-options)) +(defn debug-none! [] (reset! *debug* #{})) +(defn debug! [option] (swap! *debug* conj option)) +(defn -debug! [option] (swap! *debug* disj option)) + +(defn ^:export ^boolean debug? + [option] + (if *assert* + (boolean (@*debug* option)) + false)) + +(defn ^:export toggle-debug [name] (let [option (keyword name)] + (if (debug? option) + (-debug! option) + (debug! option)))) +(defn ^:export debug-all [] (debug-all!)) +(defn ^:export debug-none [] (debug-none!)) + +(defn ^:export tap + "Transducer function that can execute a side-effect `effect-fn` per input" + [effect-fn] + + (fn [rf] + (fn + ([] (rf)) + ([result] (rf result)) + ([result input] + (effect-fn input) + (rf result input))))) + +(defn ^:export logjs + ([str] (tap (partial logjs str))) + ([str val] + (js/console.log str (clj->js val)) + val)) + +(when (exists? js/window) + (set! (.-dbg ^js js/window) clj->js) + (set! (.-pp ^js js/window) pprint)) + + +(defonce widget-style " + background: black; + bottom: 10px; + color: white; + height: 20px; + padding-left: 8px; + position: absolute; + right: 10px; + width: 40px; + z-index: 99999; + opacity: 0.5; +") + +(defn ^:export fps + "Adds a widget to keep track of the average FPS's" + [] + (let [last (volatile! (.now js/performance)) + avg (volatile! 0) + node (-> (.createElement js/document "div") + (obj/set! "id" "fps") + (obj/set! "style" widget-style)) + body (obj/get js/document "body") + + do-thing (fn do-thing [] + (timers/raf + (fn [] + (let [cur (.now js/performance) + ts (/ 1000 (* (- cur @last))) + val (+ @avg (* (- ts @avg) 0.1))] + + (obj/set! node "innerText" (mth/precision val 0)) + (vreset! last cur) + (vreset! avg val) + (do-thing)))))] + + (.appendChild body node) + (do-thing))) + +(defn ^:export dump-state [] + (logjs "state" @st/state)) + +(defn ^:export dump-buffer [] + (logjs "state" @st/last-events)) + +(defn ^:export get-state [str-path] + (let [path (->> (str/split str-path " ") + (map d/read-string))] + (clj->js (get-in @st/state path)))) + +(defn ^:export dump-objects [] + (let [page-id (get @st/state :current-page-id)] + (logjs "state" (get-in @st/state [:workspace-data :pages-index page-id :objects])))) + +(defn ^:export dump-object [name] + (let [page-id (get @st/state :current-page-id) + objects (get-in @st/state [:workspace-data :pages-index page-id :objects]) + target (or (d/seek (fn [[_ shape]] (= name (:name shape))) objects) + (get objects (uuid name)))] + (->> target + (logjs "state")))) + +(defn ^:export dump-tree + ([] (dump-tree false false)) + ([show-ids] (dump-tree show-ids false)) + ([show-ids show-touched] + (let [page-id (get @st/state :current-page-id) + objects (get-in @st/state [:workspace-data :pages-index page-id :objects]) + components (get-in @st/state [:workspace-data :components]) + libraries (get @st/state :workspace-libraries) + root (d/seek #(nil? (:parent-id %)) (vals objects))] + + (letfn [(show-shape [shape-id level objects] + (let [shape (get objects shape-id)] + (println (str/pad (str (str/repeat " " level) + (:name shape) + (when (seq (:touched shape)) "*") + (when show-ids (str/format " <%s>" (:id shape)))) + {:length 20 + :type :right}) + (show-component shape objects)) + (when show-touched + (when (seq (:touched shape)) + (println (str (str/repeat " " level) + " " + (str (:touched shape))))) + (when (:remote-synced? shape) + (println (str (str/repeat " " level) + " (remote-synced)")))) + (when (:shapes shape) + (dorun (for [shape-id (:shapes shape)] + (show-shape shape-id (inc level) objects)))))) + + (show-component [shape objects] + (if (nil? (:shape-ref shape)) + "" + (let [root-shape (cp/get-component-shape shape objects) + component-id (when root-shape (:component-id root-shape)) + component-file-id (when root-shape (:component-file root-shape)) + component-file (when component-file-id (get libraries component-file-id nil)) + component (when component-id + (if component-file + (get-in component-file [:data :components component-id]) + (get components component-id))) + component-shape (when (and component (:shape-ref shape)) + (get-in component [:objects (:shape-ref shape)]))] + (str/format " %s--> %s%s%s" + (cond (:component-root? shape) "#" + (:component-id shape) "@" + :else "-") + (when component-file (str/format "<%s> " (:name component-file))) + (or (:name component-shape) "?") + (if (or (:component-root? shape) + (nil? (:component-id shape)) + true) + "" + (let [component-id (:component-id shape) + component-file-id (:component-file shape) + component-file (when component-file-id (get libraries component-file-id nil)) + component (if component-file + (get-in component-file [:data :components component-id]) + (get components component-id))] + (str/format " (%s%s)" + (when component-file (str/format "<%s> " (:name component-file))) + (:name component))))))))] + + (println "[Page]") + (show-shape (:id root) 0 objects) + + (dorun (for [component (vals components)] + (do + (println) + (println (str/format "[%s]" (:name component))) + (show-shape (:id component) 0 (:objects component))))))))) + +(when *assert* + (defonce debug-subscription + (->> st/stream + (rx/filter ptk/event?) + (rx/filter (fn [s] (and (debug? :events) + (not (debug-exclude-events (ptk/type s)))))) + (rx/subs #(println "[stream]: " (ptk/repr-event %)))))) +