Add a time-travelling debugger

This commit is contained in:
Daniel Compton 2018-02-13 20:10:05 +13:00
parent 05e4bf5e7b
commit 77116e3024
5 changed files with 63 additions and 15 deletions

View File

@ -7,6 +7,10 @@ All notable changes to this project will be documented in this file. This change
To take advantage of the more granular timing info in this version, you will need to upgrade to re-frame 0.10.5.
### Added
* A time-travelling debugger. Navigating forwards and backwards through the event history updates app-db to match. Be careful when using this with a stateful backend; as in the movies if you change too much or go too far back, the future can become unpredictable.
### Improved
* Improve Timing panel to show more granular timing info.

View File

@ -19,6 +19,7 @@
{id1 {:id id1 :ns-str "re-com.box" :ns 're-com.box :sort 0}
id2 {:id id2 :ns-str "re-com.input-text" :ns 're-com.input-text :sort 1}}))
num-epochs (localstorage/get "retained-epochs" 5)
follows-events? (localstorage/get "app-db-follows-events?" true)
categories (localstorage/get "categories" #{:event :sub/run :sub/create :sub/dispose})]
(when using-trace?
(rf/dispatch [:global/enable-tracing]))
@ -29,6 +30,7 @@
(rf/dispatch [:settings/set-filtered-view-trace filtered-view-trace])
(rf/dispatch [:settings/set-low-level-trace low-level-trace])
(rf/dispatch [:settings/set-number-of-retained-epochs num-epochs])
(rf/dispatch [:settings/app-db-follows-events? follows-events?])
(rf/dispatch [:settings/debug? debug?])
(when external-window?
(rf/dispatch [:global/launch-external]))

View File

@ -112,13 +112,14 @@
(fn [db _]
(assoc-in db [:settings :paused?] true)))
(rf/reg-event-db
(rf/reg-event-fx
:settings/play
(fn [db _]
(-> db
(assoc-in [:settings :paused?] false)
(assoc-in [:epochs :current-epoch-index] nil)
(assoc-in [:epochs :current-epoch-id] nil))))
(fn [{db :db} _]
{:db (-> db
(assoc-in [:settings :paused?] false)
(assoc-in [:epochs :current-epoch-index] nil)
(assoc-in [:epochs :current-epoch-id] nil))
:dispatch [:snapshot/reset-current-epoch-app-db nil]}))
(rf/reg-event-db
:settings/set-number-of-retained-epochs
@ -218,6 +219,12 @@
(fn [db [_ debug?]]
(assoc-in db [:settings :debug?] debug?)))
(rf/reg-event-db
:settings/app-db-follows-events?
[(rf/path [:settings :app-db-follows-events?]) (fixed-after #(localstorage/save! "app-db-follows-events?" %))]
(fn [db [_ follows-events?]]
follows-events?))
;; Global
(defn mount [popup-window popup-document]
@ -505,6 +512,22 @@
(reset! re-frame.db/app-db new-db)
db))
(rf/reg-event-db
:snapshot/reset-current-epoch-app-db
(fn [db [_ new-id]]
(let [follows-events? (get-in db [:settings :app-db-follows-events?])
epochs (:epochs db)
match-id (or new-id
;; new-id may be nil when we call this event from :settings/play
(utils/last-in-vec (get epochs :match-ids)))
match (get-in epochs [:matches-by-id match-id])
event (metam/matched-event (:match-info match))]
(when follows-events?
;; Don't mess up the users app if there is a problem getting app-db-after.
(when-some [new-db (get-in event [:tags :app-db-after])]
(reset! re-frame.db/app-db new-db))))
db))
;;;
(defn first-match-id
@ -555,7 +578,7 @@
event-trace (first (filter metam/event-run? epoch-traces))
finish-run (or (first (filter metam/finish-run? epoch-traces))
(utils/last-in-vec epoch-traces))]
{:re-frame/event-run-time (metam/elapsed-time start-of-epoch finish-run)
{:re-frame/event-run-time (metam/elapsed-time start-of-epoch finish-run)
:re-frame/event-time (:duration event-trace)
:re-frame/event-handler-time (:duration event-handler-trace)
:re-frame/event-dofx-time (:duration dofx-trace)}))
@ -593,10 +616,12 @@
(let [match-ids (:match-ids db)
match-array-index (utils/find-index-in-vec (fn [x] (= current-id x)) match-ids)
new-id (nth match-ids (dec match-array-index))]
{:db (assoc db :current-epoch-id new-id)
:dispatch [:settings/pause]})
{:db (assoc db :current-epoch-id (nth (:match-ids db) (- (count (:match-ids db)) 2)))
:dispatch [:settings/pause]})))
{:db (assoc db :current-epoch-id new-id)
:dispatch-n [[:settings/pause] [:snapshot/reset-current-epoch-app-db new-id]]})
(let [new-id (nth (:match-ids db)
(- (count (:match-ids db)) 2))]
{:db (assoc db :current-epoch-id new-id )
:dispatch-n [[:settings/pause] [:snapshot/reset-current-epoch-app-db new-id]]}))))
(rf/reg-event-fx
:epochs/next-epoch
@ -606,10 +631,11 @@
(let [match-ids (:match-ids db)
match-array-index (utils/find-index-in-vec (fn [x] (= current-id x)) match-ids)
new-id (nth match-ids (inc match-array-index))]
{:db (assoc db :current-epoch-id new-id)
:dispatch [:settings/pause]})
{:db (assoc db :current-epoch-id (last (:match-ids db)))
:dispatch [:settings/pause]})))
{:db (assoc db :current-epoch-id new-id)
:dispatch-n [[:settings/pause] [:snapshot/reset-current-epoch-app-db new-id]]})
(let [new-id (last (:match-ids db))]
{:db (assoc db :current-epoch-id new-id)
:dispatch-n [[:settings/pause] [:snapshot/reset-current-epoch-app-db new-id]]}))))
(rf/reg-event-db
:epochs/reset

View File

@ -68,6 +68,12 @@
(fn [settings]
(:debug? settings)))
(rf/reg-sub
:settings/app-db-follows-events?
:<- [:settings/root]
(fn [settings]
(:app-db-follows-events? settings)))
;; App DB
(rf/reg-sub

View File

@ -92,6 +92,16 @@
[[:p num-epochs " epochs currently retained, involving " num-traces " traces."]]
settings-box-81])
[rc/line]
(let [follows-events? @(rf/subscribe [:settings/app-db-follows-events?])]
[settings-box
[[rc/checkbox
:model follows-events?
:label "sync app-db with epoch navigation"
:on-change #(rf/dispatch [:settings/app-db-follows-events? %])]]
[[:p "When you navigate to an epoch, update app-db to match. Causes UI to \"time travel\"."]]
settings-box-81])
[rc/line]
[settings-box
[[rc/h-box