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.

Reply via email to