📄 timelines.c
字号:
ListCreate( list, int, 4 ); ListAddItem( list, int, 80 ); ListAddItem( list, int, 60 ); ListAddItem( list, int, 40 ); *list2 = list; return 0;}static int Cmd( clientData, interp, argc, argv )ClientData clientData;Tcl_Interp *interp;int argc;char *argv[];{ timeLineInfo *tl; tl = (timeLineInfo*)clientData; if (!strcmp( argv[1], "draw" )) { if (argc != 2) { Tcl_AppendResult( interp, "wrong # of args: ", argv[0], " draw", (char*)0 ); return TCL_ERROR; } return Draw( tl ); } else if (!strcmp( argv[1], "destroy" )) { if (argc != 2) { Tcl_AppendResult( interp, "wrong # of args: ", argv[0], " destroy", (char*)0 ); return TCL_ERROR; } return Destroy( tl ); } else if (!strcmp( argv[1], "currentitem" )) { if (argc != 2) { Tcl_AppendResult( interp, "wrong # of args: ", argv[0], " currentitem", (char*)0 ); return TCL_ERROR; } return CurrentItem( tl ); } else { Tcl_AppendResult( interp, argv[1], " -- unknown command for timeline", (char*)0 ); return TCL_ERROR; }}/* Slide the canvas with xview and yview commands so that it is in the correct position.*/int Slide( tl )timeLineInfo *tl;{ char cmd[200]; int xview, yview; xview = (tl->xleft - tl->startTime) / tl->totalTime * tl->width; if (xview != tl->xview) { tl->xview = xview; sprintf( cmd, "%s xview %d", tl->canvasName, xview ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; } yview = tl->ytop / tl->np * tl->height; if (yview != tl->yview) { tl->yview = yview; sprintf( cmd, "%s yview %d", tl->canvasName, yview ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; } return TCL_OK;}/* Stretch the canvas to fit the display settings requested.*/int Stretch( tl )timeLineInfo *tl;{ char cmd[200]; double width, height; width = tl->visWidth * tl->totalTime / tl->xspan; height = tl->visHeight * tl->np / tl->yspan; if (width != tl->width || height != tl->height) { /* unsquish calls Feather_ReconfigArrows, which unsquishes any arrows that got squished by the scale */ sprintf( cmd, "%s scale all 0 0 %.17g %.17g; unsquish %s", tl->canvasName, width / tl->width, height / tl->height, tl->canvasName ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; sprintf( cmd, "%s config -scrollregion {0 0 %.17g %.17g}", tl->canvasName, width, height ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; tl->width = width; tl->height = height; } return Slide( tl );}static int Draw( tl )timeLineInfo *tl;{ Tk_Window canvasWin; void *canvasPtr; char cmd[200]; if (TCL_OK != Feather_GetCanvasPtr( tl->interp, tl->canvasName, &canvasPtr, &canvasWin )) { return TCL_ERROR; } if (tl->visWidth == -1 || tl->visHeight == -1 || tl->xspan == -1 || tl->yspan == -1) { /* Cannot draw--no dimensions yet */ return TCL_OK; } /* If the display has already been drawn and hasn't been stretched or anything, just slide it a bit. */ if (tl->isdrawn && tl->visWidth == tl->lastVisWidth && tl->visHeight == tl->lastVisHeight && tl->xspan == tl->lastXspan && tl->yspan == tl->lastYspan) { return Slide( tl ); } tl->lastVisWidth = tl->visWidth; tl->lastVisHeight = tl->visHeight; tl->lastXspan = tl->xspan; tl->lastYspan = tl->yspan; /* if it's already been drawn, I'll just stretch it to fit. */ if (tl->isdrawn) { return Stretch( tl ); } /* well, looks like we'll actually have to draw it. */ /* set the canvas scroll region to match what I want */ tl->width = tl->visWidth * tl->totalTime / tl->xspan; tl->height = tl->visHeight * tl->np / tl->yspan; sprintf( cmd, "%s config -scrollregion {0 0 %.17g %.17g}", tl->canvasName, tl->width, tl->height ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; /* allocate Feather_Colors and stuff */ AllocColors( tl ); if (DrawBgLines( tl ) != TCL_OK || DrawEvents( tl, canvasPtr, canvasWin ) != TCL_OK || DrawStates( tl, canvasPtr, canvasWin ) != TCL_OK || DrawMsgs( tl, canvasPtr, canvasWin ) != TCL_OK) { return TCL_ERROR; } tl->isdrawn = 1; /* make sure everyone is in the right position */ return Slide( tl );}/* Draw the lines that all the state bars sit on.*/static int DrawBgLines( tl )timeLineInfo *tl;{ int i; double y; char cmd[200]; for (i=0; i<tl->np; i++) { y = Proc2Pix( tl, i+.5 ); sprintf( cmd, "%s create line 0 %f %f %f -fill %s -tags {%s}", tl->canvasName, y, tl->width, y, tl->lineColor, "color_timeline" ); if (Tcl_Eval( tl->interp, cmd ) != TCL_OK) return TCL_ERROR; } return TCL_OK;} static int DrawEvents( tl, canvasPtr, canvasWin )timeLineInfo *tl;void *canvasPtr;Tk_Window canvasWin;{/* printf( "%d events to draw\n", Log_Nevents( tl->log ) ); n = Log_Nevents( tl->log ); for (i=tl->lastEventDrawn; i<n; i++) {} tl->lastEventDrawn = i;*/ return TCL_OK;}/* The Feather_CreateRect() command wants allocated colors and bitmaps and stuff. Allocate them once with this procedure.*/static int AllocColors( tl )timeLineInfo *tl;{ int nstates, np, i; char *name, *color, *bitmap; char tag[50]; nstates = Log_NstateDefs( tl->log ); np = Log_Np( tl->log ); tl->fillColors = (Feather_Color*) malloc( sizeof(Feather_Color) * nstates ); tl->fillStipples = (Feather_Bitmap*) malloc( sizeof(Feather_Bitmap) * nstates ); tl->stateTags = (Tk_Uid*) malloc( sizeof(Tk_Uid) * nstates ); tl->colorTags = (Tk_Uid*) malloc( sizeof(Tk_Uid) * nstates ); tl->procTags = (Tk_Uid*) malloc( sizeof(Tk_Uid) * np ); Feather_GetCanvasPtr( tl->interp, tl->canvasName, &tl->canvasPtr, &tl->canvasWin ); tl->outlineCol = Feather_GetColor( tl->interp, tl->canvasWin, None, Tk_GetUid( tl->outlineColor ) ); tl->bgCol = Feather_GetColor( tl->interp, tl->canvasWin, None, Tk_GetUid( tl->bg ) ); tl->msgCol = Feather_GetColor( tl->interp, tl->canvasWin, None, Tk_GetUid( tl->msgColor ) ); tl->colorBgTag = Tk_GetUid( "color_bg" ); tl->colorOutlineTag = Tk_GetUid( "color_outline" ); tl->colorArrowTag = Tk_GetUid( "color_arrow" ); for (i=0; i<nstates; i++) { Log_GetStateDef( tl->log, i, &name, &color, &bitmap ); sprintf( tag, "state_%d", i ); tl->stateTags[i] = Tk_GetUid( tag ); sprintf( tag, "color_%d", i ); tl->colorTags[i] = Tk_GetUid( tag ); tl->fillColors[i] = Feather_GetColor( tl->interp, tl->canvasWin, None, Tk_GetUid( color ) ); tl->fillStipples[i] = Feather_GetBitmap( tl->interp, tl->canvasWin, Tk_GetUid( bitmap ) ); } for (i=0; i<np; i++) { sprintf( tag, "proc_%d", i ); tl->procTags[i] = Tk_GetUid( tag ); } return TCL_OK;}/* Free colors and stuff allocated in AllocColor.*/static int FreeColors( tl )timeLineInfo *tl;{ int nstates, i; nstates = Log_NstateDefs( tl->log ); Feather_FreeColor( tl->outlineCol ); Feather_FreeColor( tl->bgCol ); Feather_FreeColor( tl->msgCol ); for (i=0; i<nstates; i++) { Feather_FreeColor( tl->fillColors[i] ); Feather_FreeBitmap( tl->fillStipples[i] ); } return 0;}static int DrawStates( tl, canvasPtr, canvasWin )timeLineInfo *tl;void *canvasPtr;Tk_Window canvasWin;{ Feather_RectInfo rectInfo; unsigned long rectMask; int n, id, i; double x1, y1, x2, y2; Tk_Uid tags[3]; tl_stateInfo state_info; /* state info */ int type, proc, parent, firstChild, overlapLevel; double startTime, endTime; /* printf( "%d states to draw\n", Log_Nstates( tl->log ) );*/ rectInfo.tagList = tags; n = Log_Nstates( tl->log ); for (i=0; i<n; i++) { Log_GetState( tl->log, i, &type, &proc, &startTime, &endTime, &parent, &firstChild, &overlapLevel ); /* set horizontal start and end points */ x1 = Time2Pix( tl, startTime ); x2 = Time2Pix( tl, endTime ); /* set the top and bottom coordinates of the bar*/ /* the overlap.halfWidth is a number from 0 to 100; how much of the alloted space to fill up */ y1 = Proc2Pix( tl, proc + .5 * (100 - ListItem( tl->overlap.halfWidths, int, overlapLevel ))/100.0 ); y2 = Proc2Pix( tl, proc + .5 + .5 * ListItem( tl->overlap.halfWidths, int, overlapLevel )/100.0 ); /* give it tags like "proc_%d", "state_%d", and "color_bg" */ tags[0] = tl->colorBgTag;/* tags[1] = tl->procTags[proc]; tags[2] = tl->stateTags[type];*/ rectInfo.ntags = 1; /* process and state tags are not used right now--don't assign them */ /* fill with background color -- this is the coverup rectangle */ rectInfo.fillColor = tl->bgCol; rectMask = FEATHER_FILLCOLOR | FEATHER_TAGLIST; id = Feather_CreateRect( tl->interp, tl->canvasPtr, x1, y1, x2, y2, &rectInfo, rectMask ); if (id == -1) return TCL_ERROR; state_info.canvasId1 = id; /* give it tags like "color_%d" and "color_outline" */ tags[0] = tl->colorTags[type]; tags[1] = tl->colorOutlineTag; rectInfo.ntags = 2; rectMask = FEATHER_TAGLIST; if (tl->bw) { /* if in b&w, fill it in a stipple pattern with the outline color */ rectInfo.fillColor = tl->outlineCol; rectInfo.fillStipple = tl->fillStipples[type]; rectInfo.outlineColor = tl->outlineCol; rectMask |= FEATHER_FILLCOLOR | FEATHER_FILLSTIPPLE | FEATHER_OUTLINECOLOR; } else { rectInfo.fillColor = tl->fillColors[type]; rectInfo.outlineColor = tl->outlineCol; rectMask |= FEATHER_FILLCOLOR | FEATHER_OUTLINECOLOR; } id = Feather_CreateRect( tl->interp, tl->canvasPtr, x1, y1, x2, y2, &rectInfo, rectMask ); if (id == -1) return TCL_ERROR; state_info.canvasId2 = id; /* if this state has a firstChild */ if (firstChild >= 0) { /* put the rectangle below this state's first child */ id = ListItem( tl->stateList, tl_stateInfo, firstChild ).canvasId1; Feather_Lower( tl->interp, tl->canvasPtr, state_info.canvasId2, id ); Feather_Lower( tl->interp, tl->canvasPtr, state_info.canvasId1, state_info.canvasId2 ); } /* keep track of the canvas id's of each state bar */ ListAddItem( tl->stateList, tl_stateInfo, state_info ); } return TCL_OK;}static int DrawMsgs( tl, canvasPtr, canvasWin )timeLineInfo *tl;void *canvasPtr;Tk_Window canvasWin;{ Feather_LineInfo lineInfo; unsigned long lineMask; Tk_Uid tags[3]; int n, i; double points[4], sendTime, recvTime; int type, sender, receiver, size;/* printf( "%d messages to draw.\n", Log_Nmsgs( tl->log ) );*/ n = Log_Nmsgs( tl->log ); if (!n) return TCL_OK; tl->msgIds = (int*)malloc( sizeof(int) * n ); lineInfo.tagList = tags; tags[0] = tl->colorArrowTag; lineInfo.ntags = 1; lineInfo.fg = tl->msgCol; lineInfo.arrow = last; lineMask = FEATHER_FILLCOLOR | FEATHER_TAGLIST | FEATHER_ARROW; for (i=0; i<n; i++) { Log_GetMsg( tl->log, i, &type, &sender, &receiver, &sendTime, &recvTime, &size ); /* This handles any sends/receives from MPI_PROC_NULL that we might reach here */ if (sender < 0 || receiver < 0) continue; points[0] = Time2Pix( tl, sendTime ); points[1] = Proc2Pix( tl, sender + .5 ); points[2] = Time2Pix( tl, recvTime ); points[3] = Proc2Pix( tl, receiver + .5 );/* printf( "arrow from (%d,%f) to (%d,%f)\n", sender, sendTime, receiver, recvTime );*/ tl->msgIds[i] = Feather_CreateLine( tl->interp, tl->canvasPtr, 2, points, 0, &lineInfo, lineMask ); if (tl->msgIds[i] == -1) { return TCL_ERROR; } } return TCL_OK;}/* Get the current item from the canvas, figure out what kind of object it is (state, event, or message) and return the type and index of the item, for example, {state 35}*/static int CurrentItem( tl )timeLineInfo *tl;{ int i, n; int canvas_id; char cmd[TMP_CMD_LEN]; tl_stateInfo *statePtr; sprintf( cmd, "%s find withtag current", tl->canvasName ); if (TCL_OK != Tcl_Eval( tl->interp, cmd )) { return TCL_ERROR; } /* if the result string is empty, there is no current item, so return an empty string (leave result alone). */ if (tl->interp->result[0] == 0) return TCL_OK; /* get the canvas id */ sscanf( tl->interp->result, "%d", &canvas_id ); n = ListSize( tl->stateList, tl_stateInfo ); statePtr = ListHeadPtr( tl->stateList, tl_stateInfo ); for (i=0; i<n; i++,statePtr++) { if (canvas_id == statePtr->canvasId2) { /* interp->result is supposed to point to about 200 bytes of useable memory, so we can use it */ sprintf( tl->interp->result, "state %d", i ); return TCL_OK; } } /* if the id does not match any item, return empty string */ tl->interp->result[0] = 0; return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -