first previous next last contents

REG_ANNO

reg_anno            annotations;

typedef struct {
    int    job;        /* REG_ANNO */
} reg_anno;

Sent when only the annotations (tags) for a contig have been updated. It is sometimes simplest for clients to handle REG_ANNO in the same manner as REG_LENGTH. However in some cases it can be much more efficient to handle separately as it may be easier to redisplay annotations than to redisplay everything.

REG_REGISTER and REG_DEREGISTER

reg_register        c_register;
reg_deregister      c_deregister;

typedef struct {
    int    job;        /* REG_REGISTER, REG_DEREGISTER */
    int    id;         /* Registration id */
    int    type;       /* Registration type */
    int    contig;     /* Contig number */
} reg_register, reg_deregister;

Both of these notifications share the same structure. They are sent whenever a registration or deregistration of another piece of data is performed for this contig. An example of the use of this is within the stop codon display which enables use of the "Refresh" button when a contig editor is running. The id, type and contig fields here are the same as the fields with the same name from the contig_reg_t structure.

REG_HIGHLIGHT_READ

reg_highlight_read  highlight;

typedef struct {
    int    job;       /* REG_HIGHLIGHT_READ */
    int    seq;       /* Gel reading number (-ve == contig consensus) */
    int    val;       /* 1==highlight, 0==dehighlight */
} reg_highlight_read;

This is used for notifying that an individual reading has been highlighted. It's purpose is to allow displays to synchronise highlighting of data. For instance, both the contig editor and template display send and acknowledge this notification. Thus when a name in the editor is highlighted the template display will highlight the appropriate reading, and vice versa.

When seq is positive it represents the reading to highlight, otherwise it is 0 minus the contig number (not leftmost reading number).

REG_BUFFER_START and REG_BUFFER_END

reg_buffer_start    buffer_start;
reg_buffer_end      buffer_end;

typedef struct {
    int    job;
} reg_buffer_start, reg_buffer_end;

These two notifications share the same structure, which holds no information. The purpose of REG_BUFFER_START is simply as a signal that many notifications will be arriving in quick succession, until a REG_BUFFER_END request arrives. The purpose is to speed up redisplay of functions registered with many contigs.

As an example consider the enter tags function. This adds tags to many, potentially all, contigs. We can keep track of which contigs we need to send REG_ANNO requests to, and send them with code similar to the following:

/* Notify of the start of the flurry of updates */
rs.job = REG_BUFFER_START;
for (i = 0; i < NumContigs(args.io); i++) {
    if (contigs[i]&1) {
        contig_notify(args.io, i+1, (reg_data *)&rs);
    }
}

/* Now notify all the contigs that we've added tags to */
ra.job = REG_ANNO;
for (i = 0; i < NumContigs(args.io); i++) {
    if (contigs[i]&1) {
        contig_notify(args.io, i+1, (reg_data *)&ra);
    }
}

/* Notify of the end of the flurry of updates */
re.job = REG_BUFFER_END;
for (i = 0; i < NumContigs(args.io); i++) {
    if (contigs[i]&1) {
        contig_notify(args.io, i+1, (reg_data *)&re);
    }
}

Consider the action of the contig selector. This needs to refresh the display whenever any modifications are made, including annotations. The enter tags function needs to send notifications to many contigs, thus the contig selector will receive many requests. It is obviously more efficient for the contig selector to only redisplay once. The addition of BUFFER_START and BUFFER_END solve this. As we don't know exactly which functions will be registered with which contigs, the enter tags code has to notify every contig. Hence the contig selector code must keep a count on the start and end of buffers so that it only needs to redisplay on the last buffer end. This code is as follows (tidied up and much shortened for brevity):

switch(jdata->job) {
case REG_BUFFER_START:
    {
        cs->buffer_count++;
        cs->do_update = REG_BUFFER_START;
        return;
    }

case REG_BUFFER_END:
    {
        cs->buffer_count--;
        if (cs->buffer_count <= 0) {
            cs->buffer_count = 0;
            if (cs->do_update & REG_LENGTH) {
                [ Redisplay Contigs ]
            } else if (cs->do_update & REG_ANNO) {
                [ Redisplay Tags ]
            } else if (cs->do_update & REG_ORDER) {
                [ Shuffle Order]
            }
            cs->do_update = 0;
        }
        return;
    }

case REG_ANNO:
    {
        if (!cs->do_update) {
            [ Redisplay Tags ]
        } else {
            cs->do_update |= REG_ANNO;
        }
        return;
    }
/* etc */

For further examples of handling buffering see the template display code.


first previous next last contents
This page is maintained by staden-package. Last generated on 1 March 2001.
URL: http://www.mrc-lmb.cam.ac.uk/pubseq/manual/scripting_183.html