This directory contains the code that binds the D3 demo library
to Lua. Here's how to use the Lua interface:

When you load the d3demo module (e.g. require "d3demo"), you'll
get a "d3demo" table containing two functions, a set of symbols
for the data types, and a "type" table mapping data type numbers
to a string.

It is possible to import only part of the Lua interface; if you
"require 'd3demo.reader'" you only get d3demo.open(). If you
"require 'd3demo.writer'" you get d3demo.create(), and by doing
"require 'd3demo.data'" you get just the data type symbols and
the "type" table. They can be combined.

Reader interface
----------------

reader = d3demo.open(filename)

The "open" function creates a reader associated with the given
demo file. It returns a table containing the following functions,
which are bound to this instance of the reader and may be called
as either reader.func(...) or reader:func(...).

type, data = reader.next()
type, data = reader.next(n)
type, data = reader.next({n1, n2, ...})

The first form returns the next event (chunk of data) from a
demo file. The second form searches for the next event of type
n and returns it, skipping over any events in between. The third
form searches for the next event that is of any of the types
contained in the list {n1, n2, ...}. Like the second form, it
discards any events in between. The second and third forms are
of course redundant since the type check could be done in Lua,
but they can provide a major speed advantage since the discarded
events are not converted to Lua tables (for examples, the Lua
version of the print_hud_messages example is almost as fast as
the C version because of this).

"type" is set to the type of data and "data" will be assigned
a table holding the data itself. Its fields vary with the type
of data. If there is no more data (i.e. the end of the demo file
is reached), both "type" and "data" are will be nil. If an error
occurs, an exception is thrown. Note that "type" is also the
name of a Lua function and you'll probably want to pick a
different name for it.

data = reader.get_initial_data()

Returns the initial demo data chunk in the form of a string.

reader.reset()

Resets the reader, rewinding it to the beginning of the demo
(the first event after the initial data).

reader:close()

Destroys the reader and removes the reader methods from the
table. You can also call this as reader.close(), but it will
prevent the methods from being removed. Calling any of these
methods after reader:close() has been called results in
undefined behavior.

This is not done automatically on garbage collection of the
reader instance; since it is a pure Lua table it can not have
a finalizer method. This may change in a future release, e.g.
by implementing the instance as a userdata or adding a
`sentinel' userdata object to the table.

Writer interface
----------------

writer = d3demo.create(filename)

The "create" function creates a writer associated with the given
demo file. It returns a table containing the following functions,
which are bound to this instance of the writer and may be called
as either writer.func(...) or writer:func(...). Note that unlike
its C counterpart, the d3demo.create() function takes a filename
and not an I/O stream.

writer.write(type, data)

Writes data of the given type to the demo file. "type" and "data"
are the same as the ones returned by the reader, except that they
may not be nil.

writer:close()

Destroys the writer and removes the writer methods from the
table. The same issues that exist for reader.close() and
reader:close() also affect writer.close() and writer:close();
see reader:close() for more information.

Data types
----------
The global "d3demo" table (which contains the "open" and "create"
functions) also contains symbols that map to the corresponding
data types. They are identical to the ones in d3demo_data.h but
with the "D3_" prefix removed. For example, d3demo.TIME_DATA
refers to the time data type.

In addition, the "d3demo" table has a "type" table which maps
types to human-readable strings. For example,
d3demo.type[d3demo.TIME_DATA] == "time data".
