Graphics.UsingTheDougCallbackCommand - lordmundi/wikidoctest GitHub Wiki

Using the Callback Tcl Commands

« Using the doug node tcl command | EDGE User’s Guide | Using the doug camera tcl command »

EDGE provides an extensive tcl scripting ability to DSP.

The doug.callback command can be used to define a script to be called when certain stimuli occur

Simple Directions

The format of the commands are:

doug.callback add type [-tags {tags}] [-nodes {nodes}] {script}
doug.callback delete tags

where type is:

type - redraw
     - update
     - refresh
     - timer
     - pick

The doug.callback commands are best explained via examples. The following example commands should illustrate most of the usage:

doug.callback add refresh -tags ssrms -nodes "SSHY SSHP SWRY SWRP" { puddle_update }
doug.callback add update -tags animate { doug.node WRY set -pitch [expr 30.0 * %t] }
doug.callback add timer -tags flash -delay 0.1 -autoreset 1 { script }
doug.callback add pick -tags picker { script }
doug.callback delete animate

What's really going on

If the above examples are not enough info, or you need more information about a particular option, the source code implementing the doug.callback command is below:

[Show DOUG_CALLBACK_cmd source code][4]

int
DOUG_CALLBACK_cmd( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] )
{
    DOUG_CALLBACK *pcb = 0;
    char    *tags = 0;
    char    *cmd;
	int		autoreset = 1;
	double	delay = 1.0;
    int     i;
#if 0
doug.callback add type [-tags {tags}] [-nodes {nodes}] {script}
type - redraw
     - update
     - refresh
	 - timer
	 - pick
doug.callback delete tags

doug.callback add refresh -tags ssrms -nodes "SSHY SSHP SWRY SWRP" { puddle_update }
doug.callback add update -tags animate { doug.node WRY set -pitch [expr 30.0 * %t] }
doug.callback add timer -tags flash -delay 0.1 -autoreset 1 { script }
doug.callback add pick -tags picker { script }
doug.callback delete animate
#endif
    Tcl_ResetResult( interp );

    cmd = Tcl_GetString( objv[1] );
    if( !DSF_strcmpi( cmd, "add" ) )
    {
        cmd = Tcl_GetString( objv[2] );
        if( !DSF_strcmpi( cmd, "redraw" ) )
        {
            pcb = (DOUG_CALLBACK*)malloc( sizeof(DOUG_CALLBACK) );
            memset( pcb, 0, sizeof(DOUG_CALLBACK) );
            if( !DOUG_redraw_list )
                DOUG_redraw_list = pcb;
            else
                DOUG_redraw_last->pnext = pcb;
            DOUG_redraw_last = pcb;
        }
		else if( !DSF_strcmpi( cmd, "timer" ) )
		{
            pcb = (DOUG_CALLBACK*)malloc( sizeof(DOUG_CALLBACK) );
            memset( pcb, 0, sizeof(DOUG_CALLBACK) );
			pcb->delay = delay;
			pcb->reset = autoreset;
			pcb->prev_time = -999;
            if( !DOUG_timer_list )
                DOUG_timer_list = pcb;
            else
                DOUG_timer_last->pnext = pcb;
            DOUG_timer_last = pcb;
		}
		else if( !DSF_strcmpi( cmd, "pick" ) )
		{
            pcb = (DOUG_CALLBACK*)malloc( sizeof(DOUG_CALLBACK) );
            memset( pcb, 0, sizeof(DOUG_CALLBACK) );
            if( !DOUG_pick_list )
                DOUG_pick_list = pcb;
            else
                DOUG_pick_last->pnext = pcb;
            DOUG_pick_last = pcb;
		}
        else if( !DSF_strcmpi( cmd, "refresh" ) )
        {
            pcb = (DOUG_CALLBACK*)malloc( sizeof(DOUG_CALLBACK) );
            memset( pcb, 0, sizeof(DOUG_CALLBACK) );
            if( !DOUG_refresh_list )
                DOUG_refresh_list = pcb;
            else
                DOUG_refresh_last->pnext = pcb;
            DOUG_refresh_last = pcb;
        }
        else if( !DSF_strcmpi( cmd, "update" ) )
        {
            pcb = (DOUG_CALLBACK*)malloc( sizeof(DOUG_CALLBACK) );
            memset( pcb, 0, sizeof(DOUG_CALLBACK) );
            if( !DOUG_update_list )
                DOUG_update_list = pcb;
            else
                DOUG_update_last->pnext = pcb;
            DOUG_update_last = pcb;
        }
        else
        {
            Tcl_AppendResult( interp, "doug.callback add type [-tags tags] script : invalid type ", cmd, 
                " must be one of (redraw refresh update)", NULL );
            return TCL_ERROR;
        }

        for( i = 3; i < objc; i++ )
        {
            cmd = Tcl_GetString( objv[i] );
            if( !DSF_strcmpi( cmd, "-tags" ) )
            {
                i++;
                pcb->tags = strdup( Tcl_GetString( objv[i] ) );
            }
			else if( !DSF_strcmpi( cmd, "-autoreset" ) )
			{
				if( pcb == DOUG_timer_last )
				{
					i++;
					pcb->reset = atoi( Tcl_GetString( objv[i] ) );
				}
				else
				{
					Tcl_AppendResult( interp, "doug.callback add type : (-autoreset : only valid for timer callbacks)", NULL );
					return TCL_ERROR;
				}
			}
			else if( !DSF_strcmpi( cmd, "-delay" ) )
			{
				if( pcb == DOUG_timer_last )
				{
					i++;
					pcb->delay = atof( Tcl_GetString( objv[i] ) );
				}
				else
				{
					Tcl_AppendResult( interp, "doug.callback add type : (-delay : only valid for timer callbacks)", NULL );
					return TCL_ERROR;
				}
			}
            else if( !DSF_strcmpi( cmd, "-nodes" ) )
            {
                char  *node_name;
                char  *cptr = 0;
                char  *tmpbuff;
                char *sep = " \t\n{};";
                int  j, id;

                i++;
                tmpbuff = strdup( cmd = Tcl_GetString( objv[i] ) );

                /* COUNT NUMBER OF VALID NODES */
                pcb->node_cnt = 0;
                node_name = DSF_strtok_r( tmpbuff, sep, &cptr );
                while( node_name )
                {
                    if( DSF_GetNodeID( node_name ) > -1 )
                        pcb->node_cnt += 1;
                    node_name = DSF_strtok_r( 0L, sep, &cptr );
                }

                /* ALLOCATE NODE ID TABLE */
                pcb->nodes = (int*)malloc( sizeof(int) * pcb->node_cnt );

                /* LOAD NODE LIST */
                strcpy( tmpbuff, cmd );
                pcb->node_cnt = 0;
                node_name = DSF_strtok_r( tmpbuff, sep, &cptr );
                while( node_name )
                {
                    if( (id=DSF_GetNodeID( node_name )) > -1 )
                    {
                        pcb->nodes[pcb->node_cnt] = id;
                        pcb->node_cnt += 1;
                    }
                    node_name = DSF_strtok_r( 0L, sep, &cptr );
                }

                free( tmpbuff );
            }
            else if( !pcb->script )
            {
                pcb->script = objv[i];
                Tcl_IncrRefCount( objv[i] );
            }
            else
            {
                Tcl_AppendResult( interp, "doug.callback add type [-tags tags] script : syntax error", NULL );
                return TCL_ERROR;
            }
        }
    }
    else if( !DSF_strcmpi( cmd, "delete" ) )
    {
        char *sep = " \t\n{};";
        char *tok;
        char *pc;
		char *tok_ptr = 0;

        /* NOW GO THROUGH EACH LIST AND FIND TAG MATCHES */
        pc = tags = strdup( Tcl_GetString( objv[2] ) );
        while( tok = DSF_strtok_r( pc, sep, &tok_ptr ) )
        {
            pc = 0;
            DOUG_remove_scripts( &DOUG_redraw_list, &DOUG_redraw_last, tok );
            DOUG_remove_scripts( &DOUG_timer_list, &DOUG_timer_last, tok );
            DOUG_remove_scripts( &DOUG_refresh_list, &DOUG_refresh_last, tok );
            DOUG_remove_scripts( &DOUG_update_list, &DOUG_update_last, tok );
            DOUG_remove_scripts( &DOUG_pick_list, &DOUG_pick_last, tok );
        }
    }
    else
    {
        Tcl_AppendResult( interp, "doug.callback error : command ", cmd, " unknown must be one of (add delete)", NULL );
        return TCL_ERROR;
    }

    return TCL_OK;
}

« Using the doug node tcl command | EDGE User’s Guide | Using the doug camera tcl command »

[4]: javascript:toggleObj('togglecode_id0','hide','Show DOUG_CALLBACK_cmd source code','Show DOUG_CALLBACK_cmd source code','')