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','')