A Graph stores node connectivity information.
Each node is identified by a NodeId and is stored in a sorted list.
The ordering of the list does not affect updating and painting,
but may be used for when visualizing the graph in the UI.
A Mir (Music information retrieval) object
handles listening to the music via the system audio
and generates a global timebase from the beats,
along with other relevant real-time inputs based on the music
such as the low, mid, high, and overall audio level.
It can be polled from the main thread at every frame,
at which point it will compute and return the current time in beats,
and the four audio levels.
It has a buffer of about a second or so,
but should be polled frequently to avoid dropped updates.
A unique identifier that can be used to look up a Node.
We use 128 bit IDs and assume that, as long as clients generate them randomly,
they will be unique and never collide, even across different application instances.
Props contains nodes (such as effects, movies, and images)
and connectivity information (which nodes feed into which other nodes)
that describe an overall visual composition.
RenderTargets describe different instances
of the render pipeline for a given Graph.
You may want different render target for different render requirements,
for instance, a different size / shape output,
or a different frame rate.
For example,
you might use one render target at a low resolution for rendering previews,
a second render target at a resolution matching your monitor for video output,
and a third render target at an intermediate resolution
for output to a LED lighting setup.
A unique identifier that can be used to look up a RenderTarget in a RenderTargetList.
We use 128 bit IDs and assume that, as long as clients generate them randomly,
they will be unique and never collide, even across different application instances.
A RenderTargetList represents a set of render targets and their IDs.
This RenderTargetList object is only a description:
It does not contain any render state or graphics resources.
One use case of a RenderTargetList is passing it to Context.paint during rendering.
Use DFS to compute a topological ordering of the nodes in a graph (represented as a mapping.)
The input mapping must be acyclic or this function will panic.
This sort is stable (calling topo_sort_nodes a second time should be idempotent.)