Thanks, Mike. I implemented this and had to make some changes to make it work. I.e. since `register-handler` auto-injects the `pure` middleware, any of these :next-tick child handlers need to be registered via `register-base`...
I updated the wiki, hope you don't mind... :) https://github.com/Day8/re-frame/wiki/Alternative-dispatch,-routing-&-handling#multiple-handlers-for-the-one-event Cheers! On 4 April 2015 at 08:07, Mike Thompson <[email protected]> wrote: > On Saturday, April 4, 2015 at 2:53:11 PM UTC+11, Mike Thompson wrote: >> On Saturday, April 4, 2015 at 9:51:07 AM UTC+11, Karsten Schmidt wrote: >> > Thanks, Daniel. Didn't know about `dispatch-sync` and this would >> > definitely help to avoid the delay, but the fundamental question to me >> > still is how to create reactions to handler changes *outside* reagent >> > components. I'm not sure if re-frame or reagent actually supports this >> > at all. >> > >> > AFAIK `(subscribe [:tick])` only makes sense inside a component fn. >> > Given the following subscription handler: >> > >> > (register-sub :tick (fn [db _] (reaction (:tick @db)))) >> > >> > I would like do to something like to do this outside a component: >> > >> > - subscribe to :tick >> > - update dispatch-sync to dependent handler(s) >> > - setup more subscriptions (:a, :b, :c ...) >> > - have a set of components subscribing to :a, :b, :c etc. >> > >> > So every time :tick updates, everything will be re-run/re-drawn. The >> > reasons why these dependent updates should be in handlers is that some >> > of them will require results from earlier (intermediate) handler >> > updates. >> > >> > Maybe I'm barking up the wrong tree here and should just solve this >> > via core.async mult/tap or its pub/sub? >> > >> > On 3 April 2015 at 23:07, Daniel Kersten <[email protected]> wrote: >> > > Have you tried using dispatch-sync? >> > > https://github.com/Day8/re-frame/wiki/Bootstrap-An-Application#a-cheat >> > > and >> > > https://github.com/Day8/re-frame/blob/master/src/re_frame/router.cljs#L54 >> > > >> > > On Fri, 3 Apr 2015 at 22:50 Karsten Schmidt <[email protected]> wrote: >> > >> >> > >> I've been really enjoying my last month working on a largish app based >> > >> on re-frame and not run into any probs. However, today I was going to >> > >> refactor another project using animation and came across an issue >> > >> which I'm somewhat stumped by: >> > >> >> > >> I created a global tick handler, which is supposed to be an event >> > >> generator for various other handlers to update their data in the app >> > >> db. Currently this :next-tick handler re-triggers itself like shown >> > >> below and runs as predicted (~60Hz via requestAnimationFrame), but for >> > >> the purpose of this question this could be triggered at any (lower) >> > >> frequency: >> > >> >> > >> (defn re-trigger-timer [] (reagent/next-tick (fn [] (dispatch >> > >> [:next-tick])))) >> > >> >> > >> (register-handler >> > >> :next-tick >> > >> (fn [db _] >> > >> (re-trigger-timer) >> > >> (update db :tick inc))) >> > >> >> > >> Now I'd like to have other handlers which (dynamically) subscribe to >> > >> these tick changes, but they should be run without causing another >> > >> 16ms delay caused from using the subscribe/dispatch mechanism - and I >> > >> keep drawing a blank how to achieve this w/o modifying >> > >> re-frame.db/app-db directly (outside an handler). >> > >> >> > >> Of course I could create a subscription for the :tick value, run the >> > >> related code and return the computed data as derived view during >> > >> re-drawing of the related components, but that kind of defeats the >> > >> whole purpose and I'd really like these updates to happen in handlers. >> > >> I'm sure there's a better way... no?! :) >> > >> >> > >> Could someone please clarify for me? >> > >> >> > >> FWIW the demo app in question is here: >> > >> http://demo.thi.ng/geom/physics/strands.html >> > >> >> > >> For starters I'd like to update physics sim via an handler reacting to >> > >> :tick changes, but there'll be others too... >> >> >> Hi Karsten, >> >> First, its really nice to hear that re-frame has worked well for you so far!! >> >> I've read your problem description and summarized it this way: >> 1. you need to run N different tick event handlers every 16ms. >> 2. the set of "tick" event handlers changes over time. >> Some get added and removed. >> >> To state the problem anther way: you want to register N event handlers for >> the one event, but re-frame doesn't allow for that. It only allows one event >> handler to to run for an event. >> >> Also, performance is an issue here. You want those tick handlers all run as >> soon as possible. No 16ms delay. >> >> >> If that is a good description of the problem, then we need to look for >> solution by asking ... how do I get N event handlers run for the one event? >> >> There's a couple of ways of doing that but they'd all involve you "adding >> your own layer to re-frame". Here's one ... >> >> >> Sketch >> ------ >> >> In app-db, store the list of event handler ids which should be run on each >> tick. >> >> >> (register-handler >> :add-tick-handler-id ;; usage: (dispatch [:add-tick-handler-id >> :some-other-id]) >> (fn [db [_ tick-handler-id] >> (update-in db [:tick-handlers] conj tick-handler-id))) >> >> >> (register-handler >> :remove-tick-handler >> (fn [db [_ tick-handler-id] >> ...)) >> >> ;; this happens every tick >> (register-handler >> :tick >> (fn [db v] >> (let [hs (map re-frame.handlers/lookup-handler (:tick-handlers db))] >> (reduce #(%2 %1 v) db hs))) >> > > I've written this approach up as tersely as possible and I've put it into the > Wiki: > > https://github.com/Day8/re-frame/wiki/Alternative-dispatch,-routing-&-handling#multiple-handlers-for-the-one-event > > Feel free to edit that page if you think the explanation is lacking. > > -- > Mike -- Karsten Schmidt http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
