📄 mtn.c
字号:
mtn->height = mtn->visHeight * mtn->np / mtn->yspan; /* set the canvas scroll region to match what I want */ /* alloc space for"%s config -scrollregion {0 0 %d %d}", mtn->canvasName */ cmd = malloc( strlen( mtn->canvasName ) + 150 ); sprintf( cmd, "%s config -scrollregion {0 0 %d %d}", mtn->canvasName, (int)mtn->width, (int)mtn->height ); if (Tcl_Eval( mtn->interp, cmd )!=TCL_OK) { free( cmd ); return TCL_ERROR; } free( cmd ); /* create coordinate lists and temporary working arrays */ nstates = Log_NstateDefs( mtn->log ); coordLists = (xpandList*) malloc( sizeof(xpandList) * nstates ); ht = (int*) malloc( sizeof(int) * nstates ); ht_diffs = (int*) malloc( sizeof(int) * nstates ); for (i=0; i<nstates; i++) { ListCreate( coordLists[i], double, 10 ); ht[i] = 0; ht_diffs[i] = 0; } /* one interval for every pixel */ interval = mtn->totalTime / mtn->width; InitRead( mtn ); evt_idx = 0; time = mtn->startTime; /* Get the next point where events take place. If multiple events take place at a given point, gather them all. Fill the ht_diffs array with the changes of numbers of processes in each states. */ while (NextTimeStep( mtn, ht_diffs, nstates, interval, &evt_idx, &time )) { for (i=0; i<nstates; i++) { /* if a state on the bottom is increased, everyone else gets shoved up, too */ if (i) { ht_diffs[i] += ht_diffs[i-1]; } /* if this state changed, add new coordinates to get to the new height */ if (ht_diffs[i]) { ListAddItem( coordLists[i], double, Time2X( mtn, time ) ); ListAddItem( coordLists[i], double, Ht2Y( mtn, ht[i] ) ); ht[i] += ht_diffs[i]; ListAddItem( coordLists[i], double, Time2X( mtn, time ) ); ListAddItem( coordLists[i], double, Ht2Y( mtn, ht[i] ) ); } } } free( (char*)ht ); free( (char*)ht_diffs ); /* Cap off each coordinate list with the first coordinate, to make a closed polygon. If no points have been added, don't cap it off. */ max_n_coords = ListSize( coordLists[0], double ); for (i=0; i<nstates; i++) { if (ListSize( coordLists[i], double )) { ListAddItem( coordLists[i], double, ListItem( coordLists[i], double, 0 ) ); ListAddItem( coordLists[i], double, ListItem( coordLists[i], double, 1 ) ); /* get length of longest coordinate list */ if (ListSize( coordLists[i], double ) > max_n_coords) { max_n_coords = ListSize( coordLists[i], double ); } } } /* allocate array of char[25]'s into which I'll convert the coordinates */ coordStr = (dblstr*) malloc( sizeof(dblstr) * max_n_coords ); /* allocate argv array: .c create polygon <n coords> -fill x -outline x -stipple x \ -tags x <null>= (max_n_coords) + 12 words */ argv = (char**) malloc( sizeof(char*) * (max_n_coords + 12) ); argv[0] = mtn->canvasName; argv[1] = "create"; argv[2] = "polygon"; /* get direct-calling info on the canvas */ Tcl_GetCommandInfo( mtn->interp, mtn->canvasName, &cmd_info ); /* build the command for drawing each polygon */ for (i=nstates-1; i>=0; i--) { int j; char *name, *color, *bitmap; /* if there are no coords, don't draw anything */ if (ListSize( coordLists[i], double )) { /* convert each coord into a string */ for (j=0; j<ListSize( coordLists[i], double ); j++) { argv[j+3] = coordStr[j]; sprintf( coordStr[j], "%f", ListItem( coordLists[i], double, j ) ); } /* we don't need the list anymore */ ListDestroy( coordLists[i], double ); Log_GetStateDef( mtn->log, i, &name, &color, &bitmap ); argv[j+3] = "-fill";/* argv[j+5] = "-outline"; argv[j+6] = mtn->outline;*/ argv[j+5] = "-tags"; argv[j+6] = tags; argv[j+7] = "-stipple"; argv[j+9] = 0; /* { int k; printf( "Creating polygon: " ); for (k=0; k<j+9; k++) { printf( " %s", argv[k] ); } putchar( '\n' ); } */ /* draw background polygon */ /* set tag to background color tag */ sprintf( tags, "color_bg" /* , i */ ); /* set fill to background color */ argv[j+4] = mtn->bg; /* set stipple to none */ argv[j+8] = ""; /* draw the polygon */ Tcl_CallArgv( cmd_info, mtn->interp, j+9, argv ); /* draw main polygon */ /* set tag to state color tag */ sprintf( tags, "color_%d", i ); /* set fill to background color */ argv[j+4] = mtn->bw ? mtn->outline : color; /* set stipple to none */ argv[j+8] = mtn->bw ? bitmap : ""; /* draw the polygon */ Tcl_CallArgv( cmd_info, mtn->interp, j+9, argv ); } } free( (char*) argv ); free( (char*) coordStr ); free( (char*) coordLists ); /* while (HeapSize( mtn->evtHeap, mtnEvt )) { HeapPop( mtn->evtHeap, mtnEvt, evt ); if (first || time != evt.time) { printf( "time: %f\n", evt.time ); first = 0; time = evt.time; } printf( " state %d %s\n", evt.stateNo, evt.isStartEvt ? "start" : "end" ); } */ /* Well, everything is drawn where it should be, now slide it to be in the right place. */ return Slide( mtn );}/* If the data is still in the minheap, copy it out to an array.*/static int InitRead( mtn )mtnInfo *mtn;{ int i; /* if the sorted list hasn't been gathered yet, create it */ if (!mtn->evtList) { mtn->nevents = HeapSize( mtn->evtHeap, mtnEvt ); mtn->evtList = (mtnEvt*)malloc( sizeof(mtnInfo) * mtn->nevents ); for (i=0; i < mtn->nevents ; i++) { HeapPop( mtn->evtHeap, mtnEvt, mtn->evtList[i] ); } HeapDestroy( mtn->evtHeap, mtnEvt ); mtn->evtHeap = 0; } return 0;}static int NextTimeStep( mtn, ht_diffs, nstates, interval, idx_ptr, time_ptr )mtnInfo *mtn;int *ht_diffs;int nstates, *idx_ptr;double interval, *time_ptr;{ double time; int i; /* clear the diff array */ for (i=0; i<nstates; i++) { ht_diffs[i] = 0; } i = *idx_ptr; if (i >= mtn->nevents) return 0; /* get the time of the first event in line */ time = mtn->evtList[i].time; /* keep popping more events off as long as they occurred within the specified interval */ do { if (mtn->evtList[i].isStartEvt) { ht_diffs[mtn->evtList[i].stateNo]++; } else { ht_diffs[mtn->evtList[i].stateNo]--; } i++; } while (i < mtn->nevents && mtn->evtList[i].time <= time + interval); *idx_ptr = i;/* printf( "Timestep %f\n", time ); for (i=0; i<nstates; i++) { printf( " [%d] %d\n", i, ht_diffs[i] ); }*/ *time_ptr = time; return 1;}static int Slide( mtn )mtnInfo *mtn;{ int xview; int yview; char *cmd; /* alloc space for "%s xview %d", mtn->canvasName, xview */ cmd = malloc( strlen( mtn->canvasName ) + 50 ); xview = (mtn->xleft - mtn->startTime) / mtn->totalTime * mtn->width; /* if a change in the x-position has been requested, give the canvas an 'xview' command to shift it */ if (xview != mtn->xview) { mtn->xview = xview; sprintf( cmd, "%s xview %d", mtn->canvasName, xview ); /* fprintf( stderr, "%s\n", cmd ); */ if (Tcl_Eval( mtn->interp, cmd ) != TCL_OK) goto err; } yview = mtn->ytop / mtn->np * mtn->height; /* if a change in the y-position has been requested, give the canvas a 'yview' command to shift it */ if (yview != mtn->yview) { mtn->yview = yview; sprintf( cmd, "%s yview %d", mtn->canvasName, yview ); if (Tcl_Eval( mtn->interp, cmd ) != TCL_OK) goto err; } return TCL_OK; err: free( cmd ); return TCL_ERROR;} #define LINK_ELEMENT( str_name, name, type ) \ sprintf( tmp, "%s(%s,%s)", mtn->array_name, mtn->idx_prefix, str_name ); \ Tcl_LinkVar( mtn->interp, tmp, (char*)&mtn->name, type ); \/* \ fprintf( stderr, "Linking hist->%s at address %p.\n", \ str_name, (char*)&hist->name ); \*/static int LinkVars( mtn )mtnInfo *mtn;{ char *tmp; int i = TCL_LINK_INT; int f = TCL_LINK_DOUBLE; int s = TCL_LINK_STRING; /* tmp will get filled with something like "mtn(.win.0,stuff)", or ("%s(%s,%s)", mtn->array_name, mtn->idx_prefix, element_name ), to be exact. */ int max_element_len = 10; /* "canvasName" */ tmp = malloc( strlen(mtn->array_name) + 1 + strlen(mtn->idx_prefix) + 1 + max_element_len + 1 + 1 ); /* set by Tcl */ LINK_ELEMENT( "canvasName", canvasName, s ); LINK_ELEMENT( "bg", bg, s ); LINK_ELEMENT( "outline", outline, s ); LINK_ELEMENT( "bw", bw, i ); /* set by C */ LINK_ELEMENT( "startTime", startTime, f ); LINK_ELEMENT( "endTime", endTime, f ); LINK_ELEMENT( "totalTime", totalTime, f ); LINK_ELEMENT( "np", np, i ); LINK_ELEMENT( "width", width, f ); LINK_ELEMENT( "height", height, f ); LINK_ELEMENT( "visWidth", visWidth, i ); LINK_ELEMENT( "visHeight", visHeight, i ); LINK_ELEMENT( "lastVisWidth", lastVisWidth, i ); LINK_ELEMENT( "lastVisHeight", lastVisHeight, i ); LINK_ELEMENT( "xleft", xleft, f ); LINK_ELEMENT( "xspan", xspan, f ); LINK_ELEMENT( "lastXspan", lastXspan, f ); LINK_ELEMENT( "ytop", ytop, f ); LINK_ELEMENT( "yspan", yspan, f ); LINK_ELEMENT( "lastYspan", lastYspan, f ); free( tmp ); return TCL_OK;}#define UNLINK_ELEMENT( str_name ) \ sprintf( tmp, "%s(%s,%s)", mtn->array_name, mtn->idx_prefix, str_name ); \ Tcl_UnlinkVar( mtn->interp, tmp );static int UnlinkVars( mtn )mtnInfo *mtn;{ char *tmp; /* tmp will get filled with something like "mtn(.win.0,stuff)", or ("%s(%s,%s)", mtn->array_name, mtn->idx_prefix, element_name ), to be exact. */ int max_element_len = 10; /* "canvasName" */ tmp = malloc( strlen(mtn->array_name) + 1 + strlen(mtn->idx_prefix) + 1 + max_element_len + 1 + 1 ); UNLINK_ELEMENT( "canvasName" ); UNLINK_ELEMENT( "bg" ); UNLINK_ELEMENT( "outline" ); UNLINK_ELEMENT( "bw" ); UNLINK_ELEMENT( "startTime" ); UNLINK_ELEMENT( "endTime" ); UNLINK_ELEMENT( "totalTime" ); UNLINK_ELEMENT( "np" ); UNLINK_ELEMENT( "width" ); UNLINK_ELEMENT( "height" ); UNLINK_ELEMENT( "visWidth" ); UNLINK_ELEMENT( "visHeight" ); UNLINK_ELEMENT( "lastVisWidth" ); UNLINK_ELEMENT( "lastVisHeight" ); UNLINK_ELEMENT( "xleft" ); UNLINK_ELEMENT( "xspan" ); UNLINK_ELEMENT( "lastXspan" ); UNLINK_ELEMENT( "ytop" ); UNLINK_ELEMENT( "yspan" ); UNLINK_ELEMENT( "lastYspan" ); free( tmp ); return 0;}/* Close off the mountain range data structure.*/static int Close( mtn )mtnInfo *mtn;{ UnlinkVars( mtn ); if (mtn->canvasName) free( mtn->canvasName ); if (mtn->bg) free( mtn->bg ); if (mtn->outline) free( mtn->outline ); if (mtn->array_name) free( mtn->array_name ); if (mtn->idx_prefix) free( mtn->idx_prefix ); if (mtn->evtHeap) ListDestroy( mtn->evtHeap, mtnEvt ); if (mtn->evtList) free( (char*)mtn->evtList ); free( (char*) mtn ); return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -