summaryrefslogtreecommitdiff
path: root/doc/api/utils.texi
blob: 4c7c39fdf54c0728019af12fbe9ee725443b97d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
@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