So, thinking about this some more:

If you treat the system as a state machine and the events as the state
transitions (which are performed by the handlers) and the db as the current
state (basically as described in the readme), then I think changing the
active player in the same handler as placing the players move actually
makes sense.

However, rather than simply merging the two actions together, you could
take one of these approaches:

(register-handler
  :make-move
  [(enrich change-to-next-player) with-player (path :game-board)]
  (fn [board [_ cell player]]
    (assoc board cell player)))

Where change-to-next-player and with-player are defined as:

(defn change-to-next-player [db] (assoc db :current-player ...))
(defn with-player [handler] (fn [db v] (handler db (conj v (:current-player
db))))

That is, the handler only does one job and middleware is used to mix other
logic in.

Alternatively:

(register-handler
  ;make-move
  (after #(dispatch [:change-player]))
  (fn [db [_ cell]]
    (assoc-in db [:game-board cell] (:current-player db))))

That is, you have two handlers (one to make the move and one to change the
player), but the make move handler dispatches a change-player event using
the after middleware.

In both approaches, the make-move is treated as a state transition which
moves from the (game-board, player1) state to the (new-game-board, player2)
state.

I'm personally a big fan of using middleware to brush complexity under the
rug, so to say, keeping the actual handler pure and focused on a single
task (easy to test, easy to understand, potential for reuse).
For example, I'm currently experimenting with doing all server I/O and
other side-effecting logic through handler middleware and keeping my
handlers pure, subscriptions pure (in that they only rely on their db
parameter; technically I guess you could say they're not pure as they
maintain watchers and such), the components pure (again, with the caveat
that they maintain subscriptions).

On Fri, 3 Apr 2015 at 14:44 Daniel Kersten <dkers...@gmail.com> wrote:

> The relevant code is here:
> https://github.com/Day8/re-frame/blob/master/src/re_frame/router.cljs#L30-L36
>
> But yes, unless its specifically stated to be ordered, its probably best
> to treat it as an implementation detail and not rely on it.
>
> Somewhat off topic as it doesn't address Rafal's question:
>
> I once worked on a message system where I wanted handlers to run in
> parallel, but sometimes ordering (between a subset of the events) is
> important. So I implemented a "conversation" system, such that within a
> conversation, messages were strictly ordered, but multiple conversations
> could be parallel and/or interleaved and messages not part of a
> conversation were always unordered. Eg: (my-dispatch [:foo]) is unordered
> and (my-dispatch my-conversation [:foo]) is ordered with respect to other
> messages where my-conversation was set (and my-conversation is just a
> unique id of some kind).
>
> Perhaps a similar system could be built on top of re-frame.
>
> On Fri, 3 Apr 2015 at 13:29 Colin Yates <colin.ya...@gmail.com> wrote:
>
>> Thanks for the clarification - I would still be nervous about relying
>> on the sequencing though as that feels like an implementation detail.
>>
>> I am concerned though about the interpretation of "Why? Partially
>> because handlers are given a snapshot of the app-db and can't be
>> nested.". This is still a little ambiguous for me - for example, if it
>> means nested in terms of transactions then it means the opposite of
>> what you think.
>>
>> The above could be read as "each handler is given the _same_ snapshot
>> of the database" in which case event dispatch sequence is irrelevant,
>> or "the db is the result of reducing each handler onto the snapshot".
>> I really should check the code (but head elsewhere ATM).
>>
>> On 3 April 2015 at 13:07, Daniel Kersten <dkers...@gmail.com> wrote:
>> > Right, I see what you mean. I think I need to think about it some more
>> :)
>> >
>> >
>> >
>> > On Fri, 3 Apr 2015 at 12:58 Rafał Cieślak <ravici...@gmail.com> wrote:
>> >>
>> >> > That is, have the event control which player it gets applied to. This
>> >> > way the handler does not need any knowledge of this at all and can
>> use path
>> >> > middleware to focus in on only what it cares about (the game board,
>> in the
>> >> > case of selecting a cell).
>> >>
>> >> I think it's better to fetch the player in the handler, as the cell
>> >> component itself doesn't care about whose turn it is.
>> >>
>> >> But maybe your solution is more FRP-ish, I don't know. ;)
>> >>
>> >> --
>> >> 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 clojurescript+unsubscr...@googlegroups.com.
>> >> To post to this group, send email to clojurescript@googlegroups.com.
>> >> Visit this group at http://groups.google.com/group/clojurescript.
>> >
>> > --
>> > 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 clojurescript+unsubscr...@googlegroups.com.
>> > To post to this group, send email to clojurescript@googlegroups.com.
>> > Visit this group at http://groups.google.com/group/clojurescript.
>>
>> --
>> 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 clojurescript+unsubscr...@googlegroups.com.
>> To post to this group, send email to clojurescript@googlegroups.com.
>> Visit this group at http://groups.google.com/group/clojurescript.
>>
>

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to