For each contig we maintain a list of displays of this data. We register by supplying a function (of a specific type) to our registration scheme, along with any data of our own (called our client_data) that we wish to be passed back. When an operation is performed on this contig the function that we specified is called along with our own client_data and a description of the operation made. A function often does not need to be told of all changes, so when registering it's possible to list only those operations that should be responded to.
In addition to maintaining the above information, each registration contains an identifier, a time stamp, a type, and an "id" value.
The identifier is a simply number that is used to specify a single registered
data, or a group of registered data. An example of it's use is within the
contig selector; the selector is registered on all contigs, but each
registration has the same identifier. A new identifier is returned by calling
the register_id
function.
The time stamp is allocated automatically when the contig_register
function is called. It is displayed within the results manager.
The type is used to flag a registered data as belonging to a specific function. This is useful for when we wish to send a notification to all instances of a particular display, or to query whether the contig editor is running (such as performed by the stop codon display). The current types known are:
REG_TYPE_UNKNOWN REG_TYPE_EDITOR REG_TYPE_FIJ REG_TYPE_READPAIR REG_TYPE_REPEAT REG_TYPE_QUALITY REG_TYPE_TEMPLATE REG_TYPE_RESTRICTION REG_TYPE_STOPCODON REG_TYPE_CONTIGSEL REG_TYPE_CHECKASS REG_TYPE_OLIGO
The id value is used to distinguish which pieces of data are connected. Each "result" has a single id value, but may consist of multiple pieces of registered data, all sharing the same id.
So the registration consists of the following structure:
typedef struct { void (*func)( GapIO *io, int contig, void *fdata, reg_data *jdata); void *fdata; int id; time_t time; int flags; int type; int uid; /* A _unique_ identifier for this contig_reg_t */ } contig_reg_t;
The func
and fdata
are the callback functions and
client_data. uid is a number unique to all registrations, even those
that have common id values. You need not be concerned about it's use; it
is internal to the registration system.
Hence the total memory used by the registration system is an array of arrays of above structures. One array per contig, containing an array of contig_reg_t structs.
A notification of an action involves creating a reg_data structure and
sending this to one of the notification functions (such as
contig_notify
). The reg_data structure is infact a union of many
structure types; one for each notification type. In common to all these types
is the job field. This must be filled out with the current notification type.
See section The Notifications Available.
As reg_data is a union of structures, it must be access by a further
pointer indirection. For instance, to determine the position of the contig
editor cursor from a REG_CURSOR_NOTIFY
notification we need to write
"reg_data->cursor_notify->pos
" rather than simply
"reg_data->pos
". The complete list of union names can be found in
io-reg.h. The current list is summarised below. The types and use of these
structures will be discussed in further detail later.
typedef union _reg_data { /* MUST be first here and in job data structs */ int job; reg_generic generic; reg_number number; reg_join join; reg_order order; reg_length length; reg_query_name name; reg_delete delete; reg_complement complement; reg_get_lock glock; reg_set_lock slock; reg_quit quit; reg_get_ops get_ops; reg_invoke_op invoke_op; reg_params params; reg_cursor_notify cursor_notify; reg_anno annotations; reg_register c_register; reg_deregister c_deregister; reg_highlight_read highlight; reg_buffer_start buffer_start; reg_buffer_end buffer_end; } reg_data;