Docs and contracts
This commit is contained in:
parent
0211ca4b49
commit
61e1ed676c
|
@ -5,7 +5,7 @@
|
|||
(define-generics chaos
|
||||
(chaos-yield chaos evt)
|
||||
(chaos-event chaos)
|
||||
(chaos-output! chaos outputs)
|
||||
(chaos-output! chaos output)
|
||||
(chaos-label! chaos label)
|
||||
(chaos-swap! chaos thunk)
|
||||
#:fallbacks
|
||||
|
@ -13,7 +13,7 @@
|
|||
(sync e))
|
||||
(define (chaos-event c)
|
||||
never-evt)
|
||||
(define (chaos-output! c os)
|
||||
(define (chaos-output! c o)
|
||||
(void))
|
||||
(define (chaos-label! c l)
|
||||
(void))
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
(define (chaos-event c)
|
||||
(gui-event-ch c))
|
||||
(define (chaos-output! c o)
|
||||
(set-box! (gui-drawer c) o)
|
||||
(when o
|
||||
(set-box! (gui-drawer c) o))
|
||||
((gui-refresh! c)))
|
||||
(define (chaos-label! c l)
|
||||
(send (gui-frame c) set-label l))
|
||||
|
@ -60,9 +61,9 @@
|
|||
(define gl-config
|
||||
(match mode
|
||||
['draw #f]
|
||||
['compat-gl
|
||||
['gl-compat
|
||||
(new gl-config%)]
|
||||
['core-gl
|
||||
['gl-core
|
||||
(define gl-config (new gl-config%))
|
||||
(send gl-config set-legacy? #f)]
|
||||
[gl-config
|
||||
|
@ -98,10 +99,10 @@
|
|||
[make-gui
|
||||
(->* ()
|
||||
(#:mode
|
||||
(or/c (one-of/c 'draw 'compat-gl 'core-gl)
|
||||
(or/c (one-of/c 'draw 'gl-compat 'gl-core)
|
||||
(is-a?/c gl-config%))
|
||||
#:icon
|
||||
(or/c path-string? (is-a?/c bitmap%))
|
||||
(or/c #f path-string? (is-a?/c bitmap%))
|
||||
#:width
|
||||
exact-nonnegative-integer?
|
||||
#:height
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
[make-key-state
|
||||
(-> key-state?)]
|
||||
[key-state-update!
|
||||
(-> key-state? (is-a?/c key-event%)
|
||||
(-> key-state? key-event?
|
||||
any)]
|
||||
[key-state-set?
|
||||
(-> key-state? (or/c char? key-code-symbol?)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(struct pair (l r)
|
||||
#:methods gen:chaos
|
||||
[(define/generic super-yield chaos-yield)
|
||||
(define/generic super-inputs chaos-inputs)
|
||||
(define/generic super-event chaos-event)
|
||||
(define/generic super-output! chaos-output!)
|
||||
(define/generic super-label! chaos-label!)
|
||||
(define/generic super-swap! chaos-swap!)
|
||||
|
@ -18,10 +18,10 @@
|
|||
(handle-evt always-evt
|
||||
(λ (_)
|
||||
(super-yield r e)))))
|
||||
(define (chaos-inputs c)
|
||||
(define (chaos-event c)
|
||||
(match-define (pair l r) c)
|
||||
(sequence-append (super-inputs l)
|
||||
(super-inputs r)))
|
||||
(choice-evt (super-event l)
|
||||
(super-event r)))
|
||||
(define (chaos-output! c o)
|
||||
(match-define (pair l r) c)
|
||||
(match-define (cons l.o r.o) o)
|
||||
|
|
|
@ -1,10 +1,304 @@
|
|||
#lang scribble/manual
|
||||
@require[@for-label[lux
|
||||
lux/chaos
|
||||
lux/chaos/gui
|
||||
lux/chaos/gui/val
|
||||
lux/chaos/gui/key
|
||||
lux/chaos/gui/mouse
|
||||
racket/gui/base
|
||||
racket/base]]
|
||||
|
||||
@title{lux}
|
||||
@author{jay}
|
||||
@title{lux: brilliant interactive programs}
|
||||
@author{Jay McCarthy}
|
||||
|
||||
@defmodule[lux]
|
||||
|
||||
Package Description Here
|
||||
The @racketmodname[lux] module provides an efficient way to build
|
||||
interactive programs that consist of plain mathematical functions. It
|
||||
is comparable to @racketmodname[2htdp/universe], although designed to
|
||||
allow more parameterization of how the program interacts.
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@section{Structure of a @racketmodname[lux] Program}
|
||||
|
||||
A @racketmodname[lux] program chooses how it will interact be
|
||||
selecting a @tech{chaos} and calling @racket[call-with-chaos] with
|
||||
that @tech{chaos} and a thunk that calls @racket[fiat-lux] with a
|
||||
@tech{word}. @racket[fiat-lux] may be called any number of nested
|
||||
times within a call to @racket[call-with-chaos]. Each subsequent
|
||||
@racket[fiat-lux] takes over the @tech{chaos} until the @tech{word}
|
||||
completes. It is not typically possible to use @tech{word}s with
|
||||
arbitrary @tech{chaos}es, as the @tech{chaos} specifies how the
|
||||
@tech{word} interacts through events and output values.
|
||||
|
||||
When designing @tech{word}s, it is important to realize that
|
||||
@tech{word} updating functions like @racket[word-tick] do not have to
|
||||
return a @tech{word} of the same kind.
|
||||
|
||||
@defproc[(call-with-chaos [c chaos?] [t (-> any)]) any]{
|
||||
|
||||
Runs @racket[t] with @racket[c] as the current @tech{chaos}.}
|
||||
|
||||
@defproc[(fiat-lux [w word?]) any]{
|
||||
|
||||
Runs @racket[w] with the current @tech{chaos}.}
|
||||
|
||||
@section{The Word}
|
||||
|
||||
A @deftech{word} is a generic interface the encapsulates the
|
||||
interactive behavior of a @racketmodname[lux] program.
|
||||
|
||||
@defproc[(word? [x any/c]) boolean?]{
|
||||
|
||||
Identifies @tech{word}s.}
|
||||
|
||||
@defthing[gen:word any/c]{
|
||||
|
||||
The generic interface binding for @tech{word}s.}
|
||||
|
||||
The @tech{word} methods are as follows:
|
||||
|
||||
@defproc[(word-fps [w word?]) flonum?]{
|
||||
|
||||
Returns the desired rate of updating for @racket[w] as
|
||||
frames-per-second. By default, @racket[60.0] is returned.}
|
||||
|
||||
@defproc[(word-label [w word?] [frame-time flonum?]) string?]{
|
||||
|
||||
Returns a label for @racket[w] that could use @racket[frame-time] to
|
||||
show the performance of the @tech{word} rendering. By default, returns
|
||||
@racket[(lux-standard-label "Lux" frame-time)].}
|
||||
|
||||
@defproc[(word-event [w word?] [e any/c]) word?]{
|
||||
|
||||
Returns a @tech{word} based on @racket[w] that integrates the
|
||||
information from the event @racket[e]. The type of @racket[e] is
|
||||
dependent on the current @tech{chaos}. If this returns @racket[#f],
|
||||
then the @racketmodname[lux] programs stops. By default, returns
|
||||
@racket[w].}
|
||||
|
||||
@defproc[(word-tick [w word?]) word?]{
|
||||
|
||||
Returns a @tech{word} based on @racket[w] after one tick of abstract
|
||||
time. This will be called @racket[(word-fps w)] times per second. If
|
||||
this returns @racket[#f], then the @racketmodname[lux] programs stops.
|
||||
By default, returns @racket[w].}
|
||||
|
||||
@defproc[(word-output [w word?]) any/c]{
|
||||
|
||||
Returns the output value of @racket[w]. The type that this returns is
|
||||
dependent on the current @tech{chaos}. By default, returns
|
||||
@racket[#f]. @tech{chaos}es should always allow @racket[#f] and use it
|
||||
to mean "no output".}
|
||||
|
||||
@defproc[(word-return [w word?]) any/c]{
|
||||
|
||||
Returns a value for @racket[w] when the @racketmodname[lux] programs
|
||||
stops, which happens if @racket[word-event] or @racket[word-tick]
|
||||
return @racket[#f].}
|
||||
|
||||
@subsection{Helpers}
|
||||
|
||||
@defproc[(lux-standard-label [s string?] [frame-time flonum?]) string?]{
|
||||
|
||||
Returns @racket[(string-append s ": " _fts)] where @racket[_fts]
|
||||
formats @racket[frame-time] as milliseconds and as frames per
|
||||
second.}
|
||||
|
||||
@section{Chaos}
|
||||
|
||||
A @deftech{chaos} is generic interface for an empty manifestation of
|
||||
an interactive space that is given form by the @tech{word} and
|
||||
@racket[fiat-lux].
|
||||
|
||||
@subsection{Racket GUI Chaos}
|
||||
|
||||
@defmodule[lux/chaos/gui]
|
||||
|
||||
This module provides the standard @tech{chaos} that most users of
|
||||
@racketmodname[lux] will use.
|
||||
|
||||
@defproc[(make-gui [#:mode mode (or/c (one-of/c 'draw 'gl-compat 'gl-core)
|
||||
(is-a?/c gl-config%))
|
||||
'draw]
|
||||
[#:icon icon
|
||||
(or/c #f path-string? (is-a?/c bitmap%))
|
||||
#f]
|
||||
[#:width width
|
||||
exact-nonnegative-integer?
|
||||
800]
|
||||
[#:height height
|
||||
exact-nonnegative-integer?
|
||||
600])
|
||||
chaos?]{
|
||||
|
||||
Returns a @tech{chaos} that opens a GUI frame with a canvas to draw
|
||||
on. The default size of the frame is
|
||||
@racket[width]x@racket[height]. The icon for the application is set to
|
||||
@racket[icon].
|
||||
|
||||
The canvas is set up for drawing based on @racket[mode]. If
|
||||
@racket[mode] is @racket['draw], then the canvas assumes that
|
||||
@racketmodname[racket/draw] is used. If other values are used, then
|
||||
the canvas is drawn with OpenGL. If @racket[mode] is
|
||||
@racket['gl-compat], then a compatibility OpenGL profile is used. If
|
||||
@racket[mode] is @racket['gl-core], then a core OpenGL profile is
|
||||
used. If @racket[mode] is a @racket[gl-config%] object, then it is
|
||||
used to initialize the canvas.
|
||||
|
||||
The values that @racket[word-event] is called with are either
|
||||
@racket['close] (for when the window's close button is pressed), a
|
||||
@racket[key-event%] object for when keys are pressed, or a
|
||||
@racket[mouse-event%] object for when the mouse is used.
|
||||
|
||||
The values that @racket[word-output] should return are functions that
|
||||
satisfy the contract @racket[(-> real? real? (is-a?/c dc<%>) any)]
|
||||
where the first argument is the width of the canvas, the second is the
|
||||
height, and the third is the canvas's drawing context.}
|
||||
|
||||
@subsubsection{Drawing Values}
|
||||
|
||||
@defmodule[lux/chaos/gui/val]
|
||||
|
||||
This module provides a helpful function for drawing functional images
|
||||
with @racketmodname[lux/chaos/gui].
|
||||
|
||||
@defproc[(make-gui-val [#:scale? scale? boolean? #t])
|
||||
(-> pict-convertible?
|
||||
(-> real? real? (is-a?/c dc<%>) any))]{
|
||||
|
||||
Produces a function that draws @racket[pict-convertible?] values on to
|
||||
@racketmodname[lux/chaos/gui]'s drawing context. If @racket[scale?] is
|
||||
true, then the value will be scaled to file the drawing context (while
|
||||
preserving aspect ratio), otherwise the value will be drawn in the
|
||||
center as-is.}
|
||||
|
||||
@subsubsection{Tracking Keyboard State}
|
||||
|
||||
@defmodule[lux/chaos/gui/key]
|
||||
|
||||
This module provides a set of functions for tracking keyboard state
|
||||
for use inside of @racket[word-tick], rather than updating word state
|
||||
with each event as in @racket[word-event]. Such as system may be
|
||||
appropriate for interactive programs where input is only has an impact
|
||||
at a consistent tick rate.
|
||||
|
||||
@defstruct*[key-state ([keys hash?] [shift? boolean?] [control? boolean?]
|
||||
[meta? boolean?] [alt? boolean?] [mod3? boolean?]
|
||||
[mod4? boolean?] [mod5? boolean?])]{
|
||||
|
||||
Stores a mapping of which keys are presently pressed.}
|
||||
|
||||
@defproc[(make-key-state) key-state?]{
|
||||
|
||||
Produces a @racket[key-state?] object with appropriate defaults.}
|
||||
|
||||
@defproc[(key-event? [x any/c]) boolean?]{
|
||||
|
||||
Identifies key events.}
|
||||
|
||||
@defproc[(key-state-update! [ks key-state?] [ke key-event?]) any]{
|
||||
|
||||
Updates @racket[ks] with @racket[ke].}
|
||||
|
||||
@defproc[(key-state-set? [ks key-state?] [kc (or/c char? key-code-symbol?)]) boolean?]{
|
||||
|
||||
Returns true if @racket[kc] is pressed in @racket[kc].}
|
||||
|
||||
@defproc[(key-state-set?! [ks key-state?] [kc (or/c char? key-code-symbol?)]) boolean?]{
|
||||
|
||||
Returns true if @racket[kc] is pressed in @racket[kc] and sets its
|
||||
pressed status to false..}
|
||||
|
||||
@subsubsection{Tracking Mouse State}
|
||||
|
||||
@defmodule[lux/chaos/gui/mouse]
|
||||
|
||||
This module provides a set of functions for tracking mouse state
|
||||
for use inside of @racket[word-tick], rather than updating word state
|
||||
with each event as in @racket[word-event]. Such as system may be
|
||||
appropriate for interactive programs where input is only has an impact
|
||||
at a consistent tick rate.
|
||||
|
||||
@defstruct*[mouse-state ([x exact-integer?]
|
||||
[y exact-integer?]
|
||||
[left? boolean?]
|
||||
[right? boolean?]
|
||||
[middle? boolean?]
|
||||
[shift? boolean?]
|
||||
[control? boolean?]
|
||||
[meta? boolean?]
|
||||
[alt? boolean?]
|
||||
[mod3? boolean?]
|
||||
[mod4? boolean?]
|
||||
[mod5? boolean?])]{
|
||||
|
||||
Stores the active state of the mouse.}
|
||||
|
||||
@defproc[(make-mouse-state) mouse-state?]{
|
||||
|
||||
Produces a @racket[mouse-state?] object with appropriate defaults.}
|
||||
|
||||
@defproc[(mouse-event? [x any/c]) boolean?]{
|
||||
|
||||
Identifies mouse events.}
|
||||
|
||||
@defproc[(mouse-state-update! [ms mouse-state?] [me mouse-event?]) any]{
|
||||
|
||||
Updates @racket[ms] with @racket[me].}
|
||||
|
||||
@subsection{Pair Chaos}
|
||||
|
||||
@defmodule[lux/chaos/pair]
|
||||
|
||||
This module provides a @tech{chaos} that pairs two other @tech{chaos}
|
||||
objects for @racketmodname[lux] programs with multiple interfaces.
|
||||
|
||||
@defproc[(make-pair [left chaos?] [right chaos?]) chaos?]{
|
||||
|
||||
Returns a @tech{chaos} where the input event type is the union of the
|
||||
input events of @racket[left] and @racket[right] and the output type
|
||||
is a pair of the output types of @racket[left] and @racket[right].}
|
||||
|
||||
@subsection{Implementing a Chaos}
|
||||
|
||||
@defmodule[lux/chaos]
|
||||
|
||||
Users of @racketmodname[lux] will probably not need to implement
|
||||
@tech{chaos}es, but will use those that are standard.
|
||||
|
||||
@defproc[(chaos? [x any/c]) boolean?]{
|
||||
|
||||
Identifies @tech{chaos}s.}
|
||||
|
||||
@defthing[gen:chaos any/c]{
|
||||
|
||||
The generic interface binding for @tech{chaos}es.}
|
||||
|
||||
The @tech{chaos} methods are as follows:
|
||||
|
||||
@defproc[(chaos-yield [c chaos?] [e evt?]) any]{
|
||||
|
||||
Synchronizes on @racket[e] in a way safe for @racket[c]. By default,
|
||||
calls @racket[sync].}
|
||||
|
||||
@defproc[(chaos-event [c chaos?]) evt?]{
|
||||
|
||||
Returns an event that when ready returns a @racket[c] event value. By
|
||||
default, returns @racket[never-evt].}
|
||||
|
||||
@defproc[(chaos-output! [c chaos?] [o any/c]) any]{
|
||||
|
||||
Outputs @racket[o] to @racket[c]. @tech{chaos}es should always allow
|
||||
@racket[#f] and use it to mean "no output". By default, does nothing.}
|
||||
|
||||
@defproc[(chaos-label! [c chaos?] [s string?]) any]{
|
||||
|
||||
Outputs @racket[s] as the label of @racket[c]. By default, does
|
||||
nothing.}
|
||||
|
||||
@defproc[(chaos-swap! [c chaos?] [t (-> any)]) any]{
|
||||
|
||||
Calls @racket[t] while preparing @racket[c] to run a different
|
||||
@tech{word}. By default, just calls @racket[t].}
|
||||
|
|
4
word.rkt
4
word.rkt
|
@ -21,7 +21,7 @@
|
|||
(lux-standard-label "Lux" frame-time))
|
||||
(define (word-event w e) w)
|
||||
(define (word-tick w) w)
|
||||
(define (word-output w) empty)
|
||||
(define (word-output w) #f)
|
||||
(define (word-return w) w)])
|
||||
|
||||
(define (lux-standard-label l frame-time)
|
||||
|
@ -98,6 +98,8 @@
|
|||
(provide
|
||||
gen:word
|
||||
(contract-out
|
||||
[word?
|
||||
(-> any/c word?)]
|
||||
[lux-standard-label
|
||||
(-> string? flonum?
|
||||
string?)]
|
||||
|
|
Loading…
Reference in New Issue