Small example "freewheeling" app that can be modified without restarting
# Building blocks for your Freewheeling Apps

Freewheeling apps are composed of a wide variety of building blocks that you
can use in your functions, including a small number of functions that get
automatically called for you as appropriate.

## Variables you can read

* `Current_time` -- seconds since some unspecified time. Useful for managing
  durations of time (scheduling operations, etc.).

## Functions you can implement that will get automatically called

* `on.initialize(arg)` -- called when app starts up. Provides in `arg` an
  array of words typed in if you ran it from a terminal window.
  (Based on [LÖVE]https://love2d.org/wiki/love.load.)

* `on.quit()` -- called before the app shuts down.
  (Based on [LÖVE]https://love2d.org/wiki/love.quit.)

* `on.focus(start?)` -- called when the app starts or stops receiving
  keypresses. `start?` will be `true` when app starts receiving keypresses and
  `false` when keypresses move to another window.
  (Based on [LÖVE]https://love2d.org/wiki/love.focus.)

* `on.resize(w,h)` -- called when you resize the app window. Provides new
  window dimensions in `w` and `h`.
  (Based on [LÖVE]https://love2d.org/wiki/love.resize)

* `on.file_drop(file)` -- called when a file icon is dragged and dropped on
  the app window. Provides in `file` an object representing the file that was
  dropped, that will respond to the following messages:

    * `file:getFilename()` returning a string name
    * `file:read()` returning the entire file contents in a single string

  (Based on [LÖVE]https://love2d.org/wiki/love.filedropped.)

* `on.code_change()` -- called when you make changes to the app using
  [driver.love]https://git.sr.ht/~akkartik/driver.love, any time you hit
  `f4` inside driver.love, after a definition is created or modified.

* `on.draw()` -- called to draw on the window, around 30 times a second.
  (Based on [LÖVE]https://love2d.org/wiki/love.draw.)

* `on.update(dt)` -- called after every call to `on.draw`. Make changes to
  your app's variables here rather than in `on.draw`. Provides in `dt` the
  time since the previous call to `on.update`, which can be useful for things
  like smooth animations.
  (Based on [LÖVE]https://love2d.org/wiki/love.update.)

* `on.mouse_press(x,y, mouse_button)` -- called when you press down on a mouse
  button. Provides in `x` and `y` the point on the screen at which the click
  occurred, and in `mouse_button` an integer id of the mouse button pressed.
  `1` is the primary mouse button (the left button on a right-handed mouse),
  `2` is the secondary button (the right button on a right-handed mouse),
  and `3` is the middle button. Further buttons are mouse-dependent.
  (Based on [LÖVE]https://love2d.org/wiki/love.mousepressed.)

* `on.mouse_release(x,y, mouse_button)` -- called when you release a mouse
  button. Provides the same arguments as `on.mouse_press()` above.
  (Based on [LÖVE]https://love2d.org/wiki/love.mousereleased.)

* `on.mouse_move(x,y, dx,dy, istouch)` -- called when you move the mouse.
  Provides in `x` and `y` the point on the screen at which the click occurred
  and in `dx` and `dy` the amount moved since the previous call of
  `mouse_move`.
  (Based on [LÖVE]https://love2d.org/wiki/love.mousemoved.)

* `on.mouse_wheel_move(dx,dy)` -- called when you use the scroll wheel on a
  mouse that has it. Provides in `dx` and `dy` an indication of how fast the
  wheel is being scrolled. Positive values for `dx` indicate movement to the
  right. Positive values for `dy` indicate upward movement.
  (Based on [LÖVE]https://love2d.org/wiki/love.wheelmoved.)

* `on.key_press(key)` -- called when you press a key on the keyboard. Provides
  in `key` a string name for the key ([valid values]https://love2d.org/wiki/KeyConstant).
  (Based on [LÖVE]https://love2d.org/wiki/love.keypressed.)

* `on.text_input(t)` -- called when you press a key combination that yields
  (roughly) a printable character. For example, `shift` and `a` pressed
  together will call `on.textinput` with `A`.
  (Based on [LÖVE]https://love2d.org/wiki/love.textinput.)

* `on.key_release(key)` -- called when you press a key on the keyboard.
  Provides in `key` a string name for the key ([valid values]https://love2d.org/wiki/KeyConstant).
  (Based on [LÖVE]https://love2d.org/wiki/love.keyreleased, including other
  variants.)

## Functions you can call

Everything in the [LÖVE]https://love2d.org/wiki/Main_Page and
[Lua]https://www.lua.org/manual/5.1/manual.html guides is available to you,
but here's a brief summary of the most useful primitives.

### regarding the app window

* `width, height, flags = love.window.getMode()` -- returns the dimensions and
  some properties of the app window.
  (From [LÖVE]https://love2d.org/wiki/love.window.getMode.)

* `love.window.setMode(width, height, flags)` -- modify the size and
  properties of the app window. The OS may or may not act on the request.
  (From [LÖVE]https://love2d.org/wiki/love.window.setMode.)

* `x, y, displayindex = love.window.getPosition()` -- returns the coordinates and
  monitor index (if you have more than one monitor) for the top-left corner of
  the app window.
  (From [LÖVE]https://love2d.org/wiki/love.window.getPosition.)

* `App.screen.setPosition(x, y, displayindex)` -- moves the app window so its
  top-left corner is at the specified coordinates of the specified monitor.
  The OS may or may not act on the request.
  (From [LÖVE]https://love2d.org/wiki/love.window.setPosition.)

### drawing to the app window

* `love.graphics.print(text, x,y)` -- print the given `text` in the current font
  using the current color so its top-left corner is at the specified
  coordinates of the app window.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.print.)

* `love.graphics.getFont()` -- returns a representation of the current font.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.getFont.)

* `love.graphics.setFont(font)` -- switches the current font to `font`.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.setFont.)

* `love.graphics.newFont(filename)` -- creates a font from the given font
  file.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.newFont, including other
  variants.)

* `font:width(text)` returns the width of `text` in pixels when rendered using
  a given font. Good to combine with `love.graphics.getFont`.
  (From [LÖVE]https://love2d.org/wiki/Font:getWidth.)

* `love.graphics.setColor(red, green, blue, alpha)` -- sets the current color
  to be a combination of the given channels (varying from 0 to 1). `alpha` is
  a measure of opacity.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.setColor.)

* `love.graphics.line(x1,y1, x2,y2)` -- draws a line from (`x1`,`y1`) to
  (`x2`, `y2`) in the app window using the current color, clipping data for
  negative coordinates and coordinates outside (`App.screen.width`,
  `App.screen.height`)
  (From [LÖVE]https://love2d.org/wiki/love.graphics.line, including other
  variants.)

* `love.graphics.rectangle(mode, x, y, w, h)` -- draws a rectangle using the
  current color, with a top-left corner at (`x`, `y`), with dimensions `width`
  along the x axis and `height` along the y axis
  (though check out https://love2d.org/wiki/love.graphics for ways to scale
  and rotate shapes).
  `mode` is a string, either `'line'` (to draw just the outline) and `'fill'`.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.circle, including other
  variants.)

* `love.graphics.circle(mode, x, y, r)` -- draws a circle using the current
  color, centered at (`x`, `y`) and with radius `r`.
  `mode` is a string, either `'line'` and `'fill'`.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.circle, including other
  variants.)

* `love.graphics.arc(mode, x, y, r, angle1, angle2)` -- draws an arc of a
  circle using the current color, centered at (`x`, `y`) and with radius `r`.
  `mode` is a string, either `'line'` and `'fill'`.
  `angle1` and `angle2` are in [radians]https://en.wikipedia.org/wiki/Radian.
  (From [LÖVE]https://love2d.org/wiki/love.graphics.circle, including other
  variants.)

There's much more I could include here; check out [the LÖVE manual]https://love2d.org/wiki/love.graphics.

### mouse primitives

* `love.mouse.setPosition(x, y)` -- sets the current position of the mouse to
  (`x`, `y`).
  (From [LÖVE]https://love2d.org/wiki/love.mouse.setPosition.)

* `love.mouse.isDown(mouse_button)` -- returns `true` if the button
  `mouse_button` is pressed. See `on.mouse_press` for `mouse_button` codes.
  (From [LÖVE]https://love2d.org/wiki/love.mouse.isDown.)

* `love.mouse.getX()` -- returns the x coordinate of the current position of the
  mouse.
  (From [LÖVE]https://love2d.org/wiki/love.mouse.getX.)

* `love.mouse.getY()` -- returns the x coordinate of the current position of
  the mouse.
  (From [LÖVE]https://love2d.org/wiki/love.mouse.getY.)

### keyboard primitives

* `love.keyboard.isDown(key)` -- returns `true` if the given key is currently
  pressed.
  (From [LÖVE]https://love2d.org/wiki/love.keyboard.isDown.)

### interacting with files

* `io.open(filename)` -- returns a file handle that you can
  [`read()`]https://www.lua.org/manual/5.1/manual.html#pdf-file:read from or
  [`write()`]https://www.lua.org/manual/5.1/manual.html#pdf-file:write to.
  Make sure `filename` is an absolute path so that your app can work reliably
  by double-clicking on it.
  (From [Lua]https://www.lua.org/manual/5.1/manual.html#pdf-io.open.)

* `json.encode(obj)` -- returns a JSON string for an object `obj` that will
  recreate `obj` when passed to `json.decode`. `obj` can be of most types but
  has some exceptions.
  (From [json.lua]https://github.com/rxi/json.lua.)

* `json.decode(obj)` -- turns a JSON string into a Lua object.
  (From [json.lua]https://github.com/rxi/json.lua.)

* `love.filesystem.getDirectoryItems(dir)` -- returns an unsorted array of the
  files and directories available under `dir`. `dir` must be relative to
  [LÖVE's save directory]https://love2d.org/wiki/love.filesystem.getSaveDirectory.
  There is no easy, portable way in Lua/LÖVE to list directories outside the
  save dir.
  (From [LÖVE]https://love2d.org/wiki/love.filesystem.getDirectoryItems.]

* `love.filesystem.getInfo(filename)` -- returns some information about
  `filename`, particularly whether it exists (non-`nil` return value) or not.
  `filename` must be relative to [LÖVE's save directory]https://love2d.org/wiki/love.filesystem.getSaveDirectory.
  (From [LÖVE]https://love2d.org/wiki/love.filesystem.getInfo.]

* `os.remove(filename)` -- removes a file or empty directory. Definitely make
  sure `filename` is an absolute path.
  (From [Lua]https://www.lua.org/manual/5.1/manual.html#pdf-os.remove.)

There's much more I could include here; check out [the LÖVE manual]https://love2d.org/wiki/love.filesystem
and [the Lua manual]https://www.lua.org/manual/5.1/manual.html#5.7.

### desiderata

* `love.timer.getTime()` -- returns the number of seconds elapsed since some
  unspecified start time.
  (From [LÖVE]https://love2d.org/wiki/love.timer.getTime.)

* `love.system.getClipboardText()` -- returns a string with the current
  clipboard contents.
  (From [LÖVE]https://love2d.org/wiki/love.system.getClipboardText.)

* `love.system.setClipboardText(text)` -- stores the string `text` in the
  clipboard.
  (From [LÖVE]https://love2d.org/wiki/love.system.setClipboardText.)

There's much more I could include here; check out [the LÖVE manual]https://love2d.org/wiki
and [the Lua manual]https://www.lua.org/manual/5.1/manual.html.

### The freewheeling protocol with the driver

Freewheeling apps currently respond to the following commands from the driver:
  * `QUIT` -- tells the current app to quit
  * `RESTART` -- tells the current app to reinitialize after saving any settings
  * `MANIFEST` -- requests a list of definitions the app knows about. The
    app returns only definitions that were created using the freewheeling
    framework and so can be modified and errors recovered from.
  * `DEFAULT_MAP` -- requests a default map of the code. Everyone is free to
    create their own "memory palace", but this is usually a good default to
    start with.
  * `GET <name>` -- requests the source code for definition `<name>`.
  * `GET* <name> ...` -- requests source code for multiple definitions.
  * `DELETE <name>` -- requests deletion of the definition `<name>`. Only
    permitted for definitions created using the freewheeling framework, not
    lower-level definitions.
  * anything else -- is considered a new definition to be loaded into the
    app.

Commands may cause an error response, which is sent back to the driver.

In addition, any _run-time_ errors caused as the app executes are also sent
back to the driver. These don't need an explicit command from the driver.