@node Utilities @section Utilities @menu * REPL:: REPL server integrated with game loop. * Live Reloading:: Automatically reload game assets. * Miscellaneous-Utilities:: Generally useful things. @end menu @node REPL @subsection REPL @example (use-modules (sly utils repl)) @end example The Sly REPL is a cooperative REPL server that is integrated into the game loop. It is the key to live coding games with Sly. To connect to the REPL server, use the @uref{http://www.nongnu.org/geiser/, Geiser} extension for GNU Emacs. @deffn {Scheme Procedure} start-sly-repl [@var{port}] Start a cooperative REPL server that listens on the given @code{port}. By default, this port is 37146. Additionally, a process is scheduled to poll the REPL server upon every tick of the game loop. @end deffn The Sly REPL detects when the game loop throws an error and enters a special loop for debugging. When in this state, game state will not be updated or rendered. When the errors have been fixed, calling the @code{resume-game-loop} procedure will hand control back to the game loop. @deffn {Scheme Procedure} resume-game-loop Abort from the error handling loop prompt and resume the game loop. @end deffn @node Live Reloading @subsection Live Reloading @example (use-modules (sly utils live-reload)) @end example The @code{(sly live-reload)} module enables Sly programs to react to changes in the file system and reload assets automatically, which is useful when using external programs such as an image editor or map editor. Live reloading reduces the time and effort needed to see the changes made to game assets. The following example uses the @code{with-live-reload} procedure to create a texturing loading procedure that automatically reloads textures when their associated file on disk changes: @example (use-modules (sly live-reload) (sly signal) (sly texture)) (define load-texture/live (with-live-reload load-texture)) (define-signal fox (load-texture/live "fox.png")) @end example The more generic @code{watch-files} procedure can be used to implement new types of live reloading procedures. @deffn {Scheme Procedure} watch-files @var{files} @var{thunk} [@var{polling-interval}] Watch @var{files}, a list of file names, and apply @var{thunk} each time one of them changes. A signal (@pxref{Signals}) is returned that contains the current result of @var{thunk}. The @var{polling-interval} flag determines how often @var{files} are polled for changes, defaulting to two seconds. @end deffn @deffn {Scheme Procedure} with-live-reload @var{proc} [@var{polling-interval}] Return a new procedure that re-applies @code{proc} whenever the associated file is modified. The new procedure returns a signal (@pxref{Signals}) that contains the return value of @code{proc}. The first argument to @code{proc} must be a file name string. A simple polling method is used to test for updates. Files are polled every @code{polling-interval} ticks (120 by default). @end deffn @node Miscellaneous-Utilities @subsection Miscellaneous @example (use-modules (sly utils)) @end example Miscellaneous helpful procedures. @deffn {Scheme Syntax} define-guardian @var{name} @var{reaper} Define a new guardian called @code{name} and call @code{reaper} when an object within the guardian is GC'd. Reaping is ensured to happen from the same thread that is running the game loop. @end deffn @deffn {Scheme Procedure} memoize @var{proc} Return a memoizing version of @code{proc}. @end deffn @deffn {Scheme Syntax} forever @var{body} @dots{} Evaluate @code{body} in an unbounded loop. Useful in coroutines that have no end. @end deffn @deffn {Scheme Syntax} trampoline @var{proc-name} Create a new procedure that applies the procedure bound to @code{proc-name} with all given arguments. @end deffn @deffn {Scheme Syntax} chain* @var{args} (@var{proc} @dots{}) . @var{rest} Handy macro for flattening nested procedure calls where the output of an inner call is the last argument to the outer call. @example (chain* (list '(1 2) '(3 4)) (map +) (fold + 0)) ;; => 10 @end example @end deffn @deffn {Scheme Syntax} chain @var{arg} (@var{proc} @dots{}) . @var{rest} Like @code{chain*} but for a single argument. @example (chain '(1 2 3 4) (map 1+) (fold + 0)) ;; => 14 @end example @end deffn @deffn {Scheme Procedure} list->vlist* @var{lst} Convert @code{lst} and all sub-lists within to vlists. @end deffn @deffn {Scheme Procedure} list->vlist* @var{lst} @var{index} [@dots{}] Return the element at index @code{index @dots{}} in the nested vlist structure @code{vlist}. @end deffn