logic.clj

Branches > main > 4c49c77 > files / src / net / bowmap / server / logic.clj

(ns net.bowmap.server.logic
  (:require
   [net.bowmap.server.player :as player]
   [net.bowmap.server.position :as position]
   [net.bowmap.server.server :as server]
   [net.bowmap.stormbow.event :as event]))

(defmulti handle-event
  "Returns a sequence of effects and events yielded from an event."
  (fn [event]
    (::event/id event)))

; Want this to be pure, which means you need a way to encode that state change as data?
(defmethod handle-event ::event/player-joined [{::player/keys! [uuid]}]
  (dosync
    (if (@server/players uuid)
      (throw (Exception. "Player tried to join with an existing UUID"))
      (commute server/players assoc uuid {::player/uuid uuid}))
    []))

(defmethod handle-event ::event/player-left [{:keys! [::player/uuid]}]
  (dosync
    (commute server/players dissoc uuid)
    []))

(defmethod handle-event ::event/updated-player-movement [{:keys! [::player/uuid ::position/position]}]
  (dosync
    (alter (@server/players uuid) update ::position/position merge position)
    []))

; Called when the player actually moves, not just when a position is sent
(defmethod handle-event ::event/player-moved [_ _])

(defn handle-events
  "Handles the supplied event, and all events returned recursively from this one.
   Returns a seq of all effects that are yielded from handling all events recursively."
  [event]
  (reduce (fn [effects result]
            (if (::event/id result)
              (into effects (handle-events event))
              (conj effects result)))
          [] (handle-event event)))