~lthms/lycan.lisp

c50b84ab34b162f539b587fc0cfc6026bb667ad6 — Thomas Letan 1 year, 6 months ago 8b46905
feature: Clean up daemon state when a player closes its socket

When a player closes its socket, we need to (1) remove its socket from
the daemon list of players sockets, and (2) remove the player from its
instance. When an instance becomes empty, we need to “kill” it. We do
that by telling its pool it should be killed, via the ~frame-step~
function, by returning ~t~ (true).

Signed-off-by: Thomas Letan <contact@thomasletan.fr>
2 files changed, 19 insertions(+), 4 deletions(-)

M daemon/main.lisp
M daemon/scene.lisp
M daemon/main.lisp => daemon/main.lisp +10 -1
@@ 30,6 30,9 @@
  (register-player *pool* (as:socket-data socket))
  (push socket (players dm)))

(defmethod unregister-player ((dm daemon) player)
  (removef (players dm) player))

(defmethod init ((dm daemon) port)
  (as:tcp-server
   "127.0.0.1"


@@ 51,7 54,13 @@
    (register-new-player dm socket)))

(defmethod server-event-cb ((dm daemon) err)
  (print err))
  (handler-case
      (error err)
    (as:tcp-eof ()
      (let* ((socket (as:tcp-socket err))
             (player (as:socket-data socket)))
        (unregister-player dm socket)
        (unregister-player (current-instance player) player)))))

(defun main ()
  (let ((dm (make-daemon))

M daemon/scene.lisp => daemon/scene.lisp +9 -3
@@ 42,8 42,8 @@
(defmethod frame-step ((p pool) dt)
  (dolist (i (instances p))
    (when (not (frame-step i dt))
      ;; TODO: The instance is asking for us to kill her.
      )))
      (vom:info "Killing ~a because it is empty" i)
      (removef (instances p) i))))

(defclass instance ()
  ((scene :initarg :scene


@@ 63,6 63,12 @@
  (setf (current-instance player) target)
  (push player (players target)))

(defmethod unregister-player ((target instance) player)
  (removef (players target) player))

(defmethod kill? ((i instance))
  (not (eq (length (players i)) 0)))

(defmethod frame-step ((i instance) dt)
  ;; TODO: Implement gameplay here
  t)
  (kill? i))