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 -- 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.
