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.

Reply via email to