Beautiful Code [91]
* callback function describes a piece of the delta --- a file's
* contents changing, something being renamed, etc.
*/
Then comes a long, formal documentation comment, followed by the interface itself, which is a callback table whose invocation order is partially constrained:
Code View: Scroll / Show All
/** A structure full of callback functions the delta source will invoke
* as it produces the delta.
*
* Function Usage
* ==============
*
* Here's how to use these functions to express a tree delta.
*
* The delta consumer implements the callback functions described in
* this structure, and the delta producer invokes them. So the
* caller (producer) is pushing tree delta data at the callee
* (consumer).
*
* At the start of traversal, the consumer provides edit_baton, a
* baton global to the entire delta edit.
*
* Next, if there are any tree deltas to express, the producer should
* pass the edit_baton to the open_root function, to get a baton
* representing root of the tree being edited.
*
* Most of the callbacks work in the obvious way:
*
* delete_entry
* add_file
* add_directory
* open_file
* open_directory
*
* Each of these takes a directory baton, indicating the directory
* in which the change takes place, and a path argument, giving the
* path (relative to the root of the edit) of the file,
* subdirectory, or directory entry to change. Editors will usually
* want to join this relative path with some base stored in the edit
* baton (e.g. a URL, a location in the OS filesystem).
*
* Since every call requires a parent directory baton, including
* add_directory and open_directory, where do we ever get our
* initial directory baton, to get things started? The open_root
* function returns a baton for the top directory of the change. In
* general, the producer needs to invoke the editor's open_root
* function before it can get anything of interest done.
*
* While open_root provides a directory baton for the root of
* the tree being changed, the add_directory and open_directory
* callbacks provide batons for other directories. Like the
* callbacks above, they take a parent_baton and a relative path
* path, and then return a new baton for the subdirectory being
* created / modified --- child_baton. The producer can then use
* child_baton to make further changes in that subdirectory.
*
* So, if we already have subdirectories named `foo' and `foo/bar',
* then the producer can create a new file named `foo/bar/baz.c' by
* calling:
*
* - open_root () --- yielding a baton root for the top directory
*
* - open_directory (root, "foo")
*
* - open_directory (f, "foo/bar") --- yielding a baton b for `foo/bar'
*
* - add_file (b, "foo/bar/baz.c")
*
* When the producer is finished making changes to a directory, it
* should call close_directory. This lets the consumer do any
* necessary cleanup, and free the baton's storage.
*
* The add_file and open_file callbacks each ret urn a baton
* for the file being created or changed. This baton can then be
* passed to apply_textdelta to change the file's contents.
* When the producer is finished making changes to a file, it should
* call close_file, to let the consumer clean up and free the baton.
*
* Function Call Ordering
* ======================
*
* There are five restrictions on the order in which the producer
* may use the batons:
*
* 1. The producer may call open_directory, add_directory,
* open_file, add_file at most once on any given directory
* entry. delete_entry may be called at most once on any given
* directory entry and may later be followed by add_directory or
* add_file on the same directory entry. delete_entry may
* not be called on any directory entry after open_directory,
* add_directory,open_file or add_file has been called on
* that directory entry.
*