# HG changeset patch # User Steve Losh # Date 1458750232 0 # Node ID 59376ea596d4663a8faddc1e8aafa4e96a025968 # Parent de43434e631118cfb2a6c4a54779885e26a78f1f Document a few things diff -r de43434e6311 -r 59376ea596d4 Makefile --- a/Makefile Wed Mar 23 15:22:05 2016 +0000 +++ b/Makefile Wed Mar 23 16:23:52 2016 +0000 @@ -12,7 +12,7 @@ docs: docs/build/index.html -docs/build/index.html: $(docfiles) docs/title +docs/build/index.html: $(docfiles) $(apidoc) docs/title cd docs && ~/.virtualenvs/d/bin/d pubdocs: docs diff -r de43434e6311 -r 59376ea596d4 docs/03-reference.markdown --- a/docs/03-reference.markdown Wed Mar 23 15:22:05 2016 +0000 +++ b/docs/03-reference.markdown Wed Mar 23 16:23:52 2016 +0000 @@ -12,3 +12,96 @@ ## Package GGP +### GGP-PLAYER (class) + +The base class for a GGP player. Custom players should extend this. + +#### Slot NAME + +* Allocation: INSTANCE +* Type: `STRING` +* Reader: `PLAYER-NAME` + +The name of the player. + +#### Slot PORT + +* Allocation: INSTANCE +* Type: `(INTEGER 0)` +* Reader: `PLAYER-PORT` + +The port the HTTP server should listen on. + +#### Slot CURRENT-MATCH + +* Allocation: INSTANCE + +The ID of the current match the player is playing, or `nil` if it is waiting. **Do not touch this.** + +#### Slot SERVER + +* Allocation: INSTANCE + +The Clack server object of the player. **Do not touch this.** Use `start-player` and `kill-player` to start/stop the server safely. + +### KILL-PLAYER (function) + + (KILL-PLAYER PLAYER) + +Kill the HTTP server for the given player. + + This will **not** be done gently. No cleanup will be performed if the player + is in the middle of a game. Be careful. + + + +### PLAYER-SELECT-MOVE (generic function) + + (PLAYER-SELECT-MOVE PLAYER) + +Called when it's time for the player to select a move to play. + + Must return a list/symbol of the GDL move to play. Note that any symbols in + the move should be ones that are interned in the `GGP` package. The author is + aware that this sucks and welcomes suggestions on how to make it less awful. + + + +### PLAYER-START-GAME (generic function) + + (PLAYER-START-GAME PLAYER RULES ROLE START-CLOCK PLAY-CLOCK) + +Called when the game is started. + + `rules` is a list of lists/symbols representing the GDL description of the + game. Note that all symbols are interned in the `GGP` package. + + + +### PLAYER-STOP-GAME (generic function) + + (PLAYER-STOP-GAME PLAYER) + +Called when the game is stopped. + + This is a good place to do any teardown stuff your player might need, or maybe + to suggest a GC to your Lisp implementation. + + + +### PLAYER-UPDATE-GAME (generic function) + + (PLAYER-UPDATE-GAME PLAYER MOVES) + +Called after all player have made their moves. + + `moves` will be a list of moves made by the players. + + + +### START-PLAYER (function) + + (START-PLAYER PLAYER) + +Start the HTTP server for the given player. + diff -r de43434e6311 -r 59376ea596d4 docs/api.lisp --- a/docs/api.lisp Wed Mar 23 15:22:05 2016 +0000 +++ b/docs/api.lisp Wed Mar 23 16:23:52 2016 +0000 @@ -1,6 +1,8 @@ (let ((*standard-output* (make-broadcast-stream))) (ql:quickload "docparser")) +(declaim (optimize (debug 3))) ; dammit sbcl + (defparameter *index* (docparser:parse :cl-ggp)) @@ -38,10 +40,12 @@ ;;;; Documentation Utils (defun get-doc (package-name symbol-name) - (elt (docparser:query *index* - :package-name package-name - :symbol-name symbol-name) - 0)) + (let ((results (docparser:query *index* + :package-name package-name + :symbol-name symbol-name))) + (when (> (length results) 0) + (elt results 0)))) + (defun get-package-doc (package-name) ;; good god, lemon (docparser::find-package-index *index* package-name)) @@ -75,6 +79,26 @@ (defgeneric render-documentation (node symbol-name)) +(defun render-class-slot (node) + (let ((name (docparser:node-name node)) + (type (docparser:slot-type node)) + (readers (docparser:slot-readers node)) + (writers (docparser:slot-writers node)) + (accessors (docparser:slot-accessors node))) + (format t "#### Slot ~A~%~%" name ) + (format t "* Allocation: ~A~%" (docparser:slot-allocation node)) + (when type (format t "* Type: `~A`~%" type)) + (when readers (format t "* Reader~p: ~{`~A`~^, ~}~%" (length readers) readers)) + (when writers (format t "* Writer~p: ~{`~A`~^, ~}~%" (length writers) writers)) + (when accessors (format t "* Accessor~p: ~{`~A`~^, ~}~%" (length accessors) accessors)) + (format t "~%") + (render-docstring node))) + + +(defmethod render-documentation ((node docparser:class-node) symbol-name) + (render-symbol-header symbol-name " (class)") + (render-docstring node) + (mapc #'render-class-slot (docparser:record-slots node))) (defmethod render-documentation ((node docparser:documentation-node) symbol-name) (render-symbol-header symbol-name "") @@ -90,6 +114,11 @@ (render-lambda-list node) (render-docstring node)) +(defmethod render-documentation ((node docparser:generic-function-node) symbol-name) + (render-symbol-header symbol-name " (generic function)") + (render-lambda-list node) + (render-docstring node)) + (defmethod render-documentation ((node docparser:macro-node) symbol-name) (render-symbol-header symbol-name " (macro)") (render-lambda-list node) @@ -100,7 +129,7 @@ (defun document-symbol (package-name symbol) (let* ((symbol-name (symbol-name symbol)) (doc-node (get-doc package-name symbol-name))) - (render-documentation doc-node symbol-name))) + (when doc-node (render-documentation doc-node symbol-name)))) (defun document-package (package-name) (render-package-header package-name) diff -r de43434e6311 -r 59376ea596d4 src/ggp.lisp --- a/src/ggp.lisp Wed Mar 23 15:22:05 2016 +0000 +++ b/src/ggp.lisp Wed Mar 23 16:23:52 2016 +0000 @@ -10,15 +10,57 @@ ;;;; GGP Player (defclass ggp-player () - ((name :initarg :name :initform "CL-GGP" :reader player-name) - (port :initarg :port :initform 9999 :reader player-port) - (current-match :initform nil) - (server))) + ((name + :initarg :name + :initform "CL-GGP" + :reader player-name + :type string + :documentation "The name of the player.") + (port + :initarg :port + :initform 9999 + :reader player-port + :type (integer 0) + :documentation "The port the HTTP server should listen on.") + (current-match + :initform nil + :documentation "The ID of the current match the player is playing, or `nil` if it is waiting. **Do not touch this.**") + (server + :documentation "The Clack server object of the player. **Do not touch this.** Use `start-player` and `kill-player` to start/stop the server safely.")) + (:documentation "The base class for a GGP player. Custom players should extend this.")) + + +(defgeneric player-start-game (player rules role start-clock play-clock) + (:documentation "Called when the game is started. + + `rules` is a list of lists/symbols representing the GDL description of the + game. Note that all symbols are interned in the `GGP` package. -(defgeneric player-start-game (player rules role start-clock play-clock)) -(defgeneric player-update-game (player moves)) -(defgeneric player-select-move (player)) -(defgeneric player-stop-game (player)) + ")) + +(defgeneric player-update-game (player moves) + (:documentation "Called after all player have made their moves. + + `moves` will be a list of moves made by the players. + + ")) + +(defgeneric player-select-move (player) + (:documentation "Called when it's time for the player to select a move to play. + + Must return a list/symbol of the GDL move to play. Note that any symbols in + the move should be ones that are interned in the `GGP` package. The author is + aware that this sucks and welcomes suggestions on how to make it less awful. + + ")) + +(defgeneric player-stop-game (player) + (:documentation "Called when the game is stopped. + + This is a good place to do any teardown stuff your player might need, or maybe + to suggest a GC to your Lisp implementation. + + ")) (defmethod player-start-game ((player ggp-player) rules role start-clock play-clock) @@ -109,12 +151,13 @@ (l "UNKNOWN REQUEST: ~S~%~%" unknown-request) 'what))) + +;;;; Boilerplate (defun should-log-p (request) (match request (`(info) nil) (_ t))) -;;;; Boilerplate (defun app (player env) (let* ((body (get-body env)) (request (safe-read-from-string body)) @@ -134,6 +177,7 @@ ;;;; Spinup/spindown (defun start-player (player) + "Start the HTTP server for the given player." (let* ((player-handler #'(lambda (env) (app player env))) (server (clack:clackup player-handler :port (player-port player)))) @@ -141,4 +185,10 @@ player)) (defun kill-player (player) + "Kill the HTTP server for the given player. + + This will **not** be done gently. No cleanup will be performed if the player + is in the middle of a game. Be careful. + + " (clack.handler:stop (slot-value player 'server)))