(in-package :remote-snake-server-api) (defclass api () ((gm :initform (make-instance 'game-manager)) (games-syn :initform '()))) (defmethod create-syn ((api api) game-id &optional (initial-value 0)) (unless (eq nil (get-syn api game-id)) (error "This game ~a already have a syn !" game-id)) (with-slots (games-syn) api (push (list :game-id game-id :syn initial-value) games-syn) initial-value)) (defmethod refresh-syn ((api api) game-id) (with-slots (games-syn) api (incf (getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn)))) (defmethod get-syn ((api api) game-id) (with-slots (games-syn) api (getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn))) ;;; TODO: Handle errors (valid json etc..) (defun parse-request (request) (flet ((normalizer (key) (string-upcase key))) (let ((p-request (parse request :normalize-all t :keyword-normalizer #'normalizer ))) p-request))) (defmethod handle-new-game ((api api) data) (with-slots (gm) api (let* ((game-id (create-game gm)) (game-syn (create-syn api game-id 1))) ; Create syn with 1 (since first packet already receive) (let ((game-dump (dump gm game-id))) (setf (getf game-dump :game-over) :null) ; Define nil as null (for json) (to-json (append (list :type "state" :syn game-syn) game-dump)))))) ;;; TODO: RETURN JSON !!!! (defmethod handle-update ((api api) data) (with-slots (gm) api (let* ((dir (getf data :direction)) (game-id (getf data :game-id)) (game (get-game gm game-id))) (cond ((equal dir "up") (setf dir :up)) ((equal dir "down") (setf dir :down)) ((equal dir "left") (setf dir :left)) ((equal dir "right") (setf dir :right)) (t (setf dir nil))) (if dir (refresh game :dir dir) (refresh game))))) (defmethod handle-request ((api api) request) (let* ((data (parse-request request)) (type (getf data :type))) (cond ((equal type "new-game") (handle-new-game api data)) ((equal type "update") (handle-update api data)) (t (format t "Unknow type")))))