;; ported-from: src/games/host/seance-host.ts @ v1.3.0
;; (itself: game4/client/src/game/game.ts hi/pk routing, split-brain
;; lowest-id rule, séance counter @ 12d701e) — the sim lives in
;; seance-sim.cljs; roster/timers/auto-start in the driver base.
;; divergences: no GONE_GRACE pending-gone map (peer-kit's peerGone already
;; sits behind the redial ladder; bots don't suspend) and no ensureHost()
;; backstop (designated-host v1 — see driver.cljs header).
(ns ardegazu.peer.games.host.seance-host
(:require [ardegazu.peer.games.host.driver :as driver]
[ardegazu.peer.games.host.seance-sim :as seance-sim]
[shadow.cljs.modern :refer (defclass)]))
(defclass SeanceHost
(extends driver/HostDriver)
(constructor [this room opts]
(super room (if ^boolean (js* "~{} == null" opts) (js-obj) opts))
(unchecked-set this "_seance" 0)
(unchecked-set
this "sim"
(seance-sim/SeanceSim.
(js-obj "rng" (when (some? opts) (unchecked-get opts "rng"))
"roster" (fn [] (driver/roster-entries this))
"addWin" (fn [id]
(let [p (.get ^js (unchecked-get this "roster") id)]
(when ^boolean (js* "!!(~{})" p)
(unchecked-set p "score" (inc (unchecked-get p "score")))))
js/undefined))))))
(let [proto (.-prototype SeanceHost)]
;; séance split-brain rule: plain lowest id — liveness is not consulted.
(unchecked-set proto "concedeRule"
(fn [from _m]
(this-as self (< from (unchecked-get (unchecked-get self "room") "myId")))))
(unchecked-set
proto "startMatch"
(fn [ids]
(this-as self
;; the browser sorts the séance order (hostStartSeance)
(unchecked-set self "_seance" (inc (unchecked-get self "_seance")))
(driver/run-emit self (seance-sim/start (unchecked-get self "sim")
(unchecked-get self "_seance")
(.sort (.slice ^js ids))))
js/undefined)))
(unchecked-set
proto "onGameFrame"
(fn [from m]
(this-as self
(let [t (unchecked-get m "t")]
(cond
(identical? t "hi") (driver/on-hi self from m)
(identical? t "pk") (driver/run-emit
self
(seance-sim/pick (unchecked-get self "sim") from
(bit-or (unchecked-get m "r") 0)))
:else nil))
js/undefined)))
(unchecked-set proto "execStep"
(fn [step] (this-as self
(driver/run-emit self (seance-sim/step (unchecked-get self "sim") step))
js/undefined)))
(unchecked-set proto "simPeerGone"
(fn [id] (this-as self
(driver/run-emit self (seance-sim/peer-gone (unchecked-get self "sim") id))
js/undefined)))
(unchecked-set proto "sendSnap"
(fn [to] (this-as self
(driver/run-emit self (seance-sim/snapshot (unchecked-get self "sim") to))
js/undefined)))
;; the séance protocol has no "ro".live flag
(unchecked-set proto "roundLive" (fn [] false))
(unchecked-set proto "simRunning"
(fn [] (this-as self (unchecked-get (unchecked-get self "sim") "_running"))))
(unchecked-set proto "abortSim"
(fn [] (this-as self (seance-sim/abort (unchecked-get self "sim"))))))