⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trend.cc

📁 Develop Zigbee network real-time Os
💻 CC
📖 第 1 页 / 共 2 页
字号:
  glEnd();  // scan for all intersections  size_t trX = (static_cast<size_t>(floor(intrX)));  if(trX == divisions) --trX;  double mul = (intrX - trX);  vector<Intr> intrs;  // starting position  size_t i;  const Value* it;  if(scroll)  {    it = rrBuf + (trX - offset % divisions);    i = trX;  }  else  {    it = rrBuf + (trX - rrBuf->count);    i = 0;  }  if(it < rrBuf)    it += divisions;  if(intrFg)    it += ((rrEnd - it) / divisions) * divisions;  const Value* end = rrEnd - 1;  for(; it < end; i += divisions, it += divisions)  {    size_t pos = getPosition(i, *it);    // fetch the next value    Value next = *(it + 1);        Intr buf;    if(mul < 0.5)    {      buf.near.value = it->value;      buf.near.count = pos;    }    else    {      buf.near.value = next.value;      buf.near.count = getPosition(i + 1, next);    }    buf.value = it->value + mul * (next.value - it->value);    buf.dist = fabs(buf.value - intrY);    intrs.push_back(buf);  }  // no intersections found  if(!intrs.size())    return;  // consider only the nearest n values  std::sort(intrs.begin(), intrs.end());  if(intrs.size() > static_cast<size_t>(Trend::intrNum))    intrs.resize(Trend::intrNum);  // draw intersections and estimate mean value  double mean = 0;  glBegin(GL_LINES);  for(vector<Intr>::const_iterator it = intrs.begin();      it != intrs.end(); ++it)  {    mean += it->value;    glVertex2d(0, it->value);    glVertex2d(divisions, it->value);  }  glEnd();  mean /= intrs.size();  // switch to video coordinates  glPushMatrix();  glLoadIdentity();  gluOrtho2D(0, width, 0, height);  // nearest point  int nearX, nearY;  project(intrs[0].near.count, intrs[0].near.value, nearX, nearY);  drawCircle(nearX, nearY);  if(!intrs[0].near.count)    drawCircle(width, nearY);  // plot values  using Trend::strSpc;  char buf[256];  int curY = height;  sprintf(buf, "nearest: %g, mean: %g", intrs[0].near.value, mean);  drawString(strSpc, curY -= Trend::fontHeight + strSpc, buf);  i = 1;  for(vector<Intr>::const_iterator it = intrs.begin();      it != intrs.end(); ++i, ++it)  {    sprintf(buf, "%d: %g", i, it->value);    drawString(strSpc, curY -= Trend::fontHeight + strSpc, buf);  }  // restore model space  glPopMatrix();}voiddrawValues(){  const Value& last = rrBuf[history - 1];  char buf[Trend::maxNumLen];  glColor3fv(textCol);  sprintf(buf, "%g", loLimit);  drawOSString(width, 0, buf);  sprintf(buf, "%g", hiLimit);  drawOSString(width, height, buf);  sprintf(buf, "%g", last.value);  drawLEString(buf);}voiddrawLatency(){  char buf[Trend::maxNumLen];  glColor3fv(textCol);  sprintf(buf, "lat: %g", atLat.avg());  drawLEString(buf);}// redraw handlervoiddisplay(){  // reset some data  lc = 0;  // setup model coordinates  double zero = (distrib?      -(static_cast<double>(Trend::distribWidth) * divisions /	  (width - Trend::distribWidth)): 0);  glClear(GL_COLOR_BUFFER_BIT);  glLoadIdentity();  gluOrtho2D(zero, divisions, loLimit, hiLimit);  // background grid  if(grid) drawGrid();  size_t pos = drawLine();  // other data  if(distrib) drawDistrib();  if(marker) drawMarker(pos);  if(intr) drawIntr();  // setup video coordinates  glLoadIdentity();  gluOrtho2D(0, width, 0, height);  // video stuff  if(values) drawValues();  if(latency) drawLatency();  // flush buffers  glutSwapBuffers();  atLat.stop();}voidremoveNANs(){  const Value* begin = rrBuf;  Value* it = rrEnd;  double old = NAN;  while(it-- != begin)  {    if(isnan(it->value))      it->value = old;    else if(it->value != old)      old = it->value;  }}voidsetLimits(){  const Value* it = rrBuf;  const Value* end = rrEnd;  double lo(it->value);  double hi(lo);  for(; it != end; ++it)  {    if(it->value > hi)      hi = it->value;    if(it->value < lo)      lo = it->value;  }  // some vertical bounds  hiLimit = hi + grSpec.y.res;  loLimit = lo - grSpec.y.res;}voididle(int){  // re-register the callback  glutTimerFunc(1, idle, 0);  if(paused)    return;  // check if a redraw is really necessary  bool recalc = false;#ifdef __sgi  if(test_and_set((unsigned long*)(&damaged), 0))    recalc = true;#else  // linux seems to support some unportable atomic stuff into asm/atomic  pthread_mutex_lock(&mutex);  if(damaged)  {    damaged = 0;    recalc = true;  }  pthread_mutex_unlock(&mutex);#endif  if(recalc)  {    atLat.start();    rrData->copy(rrBuf);    // since we swiched from deque to rr, the size now is always fixed, and    // the initial buffer is filled with NANs. We don't want NANs however,    // and we don't want to handle this lone-case everywhere.    if(isnan(rrBuf->value))      removeNANs();    // recalculate limits seldom    if(autoLimit)      setLimits();    glutPostRedisplay();  }}/* * Keyboard interaction */// Parse a grid (res+mayor)voidparseGrid(Grid& grid, char* spec){  char* p = strchr(spec, '+');  if(p)  {    *p++ = 0;    if(*p) grid.mayor = strtoul(p, NULL, 0);  }  if(*spec) grid.res = strtod(spec, NULL);}// Parse a grid-specvoidparseGrSpec(GrSpec& grid, char* spec){  char* p = strchr(spec, 'x');  if(p)  {    *p++ = 0;    if(*p) parseGrid(grid.x, p);  }  if(*spec) parseGrid(grid.y, spec);}voidtoggleStatus(const char* str, bool& var){  var = !var;  std::cout << str << ": " << (var? "enabled": "disabled") << std::endl;}doublegetUnit(const char* str){  cout << str << "? ";  double u;  cin >> u;  return u;}voidgetGrid(){  char buf[256];  cout << "grid-spec? ";  cin.get(buf, sizeof(buf));  parseGrSpec(grSpec, buf);  cin.get();}voidkeyboard(const unsigned char key, const int x, const int y){  switch(key)  {  case Trend::quitKey:    exit(Trend::success);    break;  // redraw alteration  case Trend::dimmedKey:    toggleStatus("dimmed", dimmed);    break;  case Trend::distribKey:    toggleStatus("distribution", distrib);    break;  case Trend::autolimKey:    toggleStatus("autolimit", autoLimit);    break;  case Trend::resetlimKey:    setLimits();    cout << "limits reset\n";    break;  case Trend::setlimKey:    loLimit = getUnit("-y");    hiLimit = getUnit("+y");    autoLimit = false;    break;  case Trend::smoothKey:    toggleStatus("smoothing", smooth);    init();    break;  case Trend::scrollKey:    toggleStatus("scrolling", scroll);    break;  case Trend::valuesKey:    toggleStatus("values", values);    break;  case Trend::markerKey:    toggleStatus("marker", marker);    break;  case Trend::gridKey:    toggleStatus("grid", grid);    break;  case Trend::setResKey:    getGrid();    break;  case Trend::latKey:    toggleStatus("latency", latency);    break;  case Trend::pauseKey:    toggleStatus("paused", paused);  default:    return;  }  glutPostRedisplay();}voidmotion(int x, int y){  unproject(x, y, intrX, intrY);  // the x position must be adjusted  if(intrX < 0)    intrX = 0.;  else if(intrX > divisions)    intrX = static_cast<double>(divisions);  glutPostRedisplay();}voidmouse(int button, int state, int x, int y){  // cause a motion event internally  intr = (button != GLUT_RIGHT_BUTTON);  intrFg = (glutGetModifiers() & GLUT_ACTIVE_CTRL);  motion(x, y);}/* * CLI and options */// Parse a hist/n, div*n, div specboolparseHistSpec(size_t& hist, size_t& div, const char* spec){  // find the separator first.  // TODO: * is deprecated  const char* p = strpbrk(spec, "/*x");  if((p == spec) || (p && *(p + 1) == 0))    return true;  if(!p)  {    div = strtoul(spec, NULL, 0);    hist = div + 1;    return false;  }  else if(*p == '/')  {    hist = strtoul(spec, NULL, 0);    div = strtoul(p + 1, NULL, 0);    if(!div) return true;    div = hist / div;  }  else  {    div = strtoul(spec, NULL, 0);    hist = div * strtoul(p + 1, NULL, 0);  }  return false;}boolparseInput(Trend::input_t& input, const char* arg){  switch(arg[0])  {  case 'a': input = Trend::absolute; break;  case 'i': input = Trend::incremental; break;  case 'd': input = Trend::differential; break;  default:    return true;  };  return false;}boolparseFormat(Trend::format_t& format, const char* arg){  switch(arg[0])  {  case 'a': format = Trend::f_ascii; break;  case 'f': format = Trend::f_float; break;  case 'd': format = Trend::f_double; break;  case 's': format = Trend::f_short; break;  case 'i': format = Trend::f_int; break;  case 'l': format = Trend::f_long; break;  default:    return true;  };  return false;}// Initialize globals through command lineintparseOptions(int argc, char* const argv[]){  // starting options  memcpy(backCol, Trend::backCol, sizeof(backCol));  memcpy(textCol, Trend::textCol, sizeof(textCol));  memcpy(gridCol, Trend::gridCol, sizeof(gridCol));  memcpy(lineCol, Trend::lineCol, sizeof(lineCol));  memcpy(markCol, Trend::markCol, sizeof(markCol));  memcpy(intrCol, Trend::intrCol, sizeof(intrCol));  grSpec.x.res = grSpec.y.res = Trend::gridres;  grSpec.x.mayor = grSpec.y.mayor = Trend::mayor;  int arg;  while((arg = getopt(argc, argv, "dDFSsvlmgG:ht:A:E:R:I:M:N:irz:f:c:")) != -1)    switch(arg)    {    case 'd':      dimmed = !dimmed;      break;    case 'D':      distrib = !distrib;      break;         case 'F':      fifo = !fifo;      break;    case 'S':      smooth = !smooth;      break;    case 's':      scroll = !scroll;      break;    case 'v':      values = !values;      break;    case 'l':      latency = !latency;      break;    case 'm':      marker = !marker;      break;    case 'g':      grid = !grid;      break;    case 'G':      parseGrSpec(grSpec, optarg);      break;    case 'z':      grZero = strtod(optarg, NULL);      break;    case 't':      title = optarg;      break;    case 'A':      parseColor(backCol, optarg);      break;    case 'E':      parseColor(textCol, optarg);      break;    case 'R':      parseColor(gridCol, optarg);      break;    case 'I':      parseColor(lineCol, optarg);      break;    case 'M':      parseColor(markCol, optarg);      break;    case 'N':      parseColor(intrCol, optarg);      break;    case 'c':      if(parseInput(input, optarg))      {	cerr << argv[0] << ": bad input mode\n";	return -1;      }      break;    case 'i':      // TODO: deprecated      input = Trend::incremental;      break;    case 'r':      // TODO: deprecated      input = Trend::differential;      break;    case 'f':      if(parseFormat(format, optarg))      {	cerr << argv[0] << ": bad format type\n";	return -1;      }      break;    case 'h':      cout << argv[0] << " usage: " <<	argv[0] << " [options] fifo <hist-spec|hist-sz x-div> [-y +y]\n" <<	argv[0] << " version: $Revision: #44 $ $Date: 2005/07/23 $\n";      return 1;    default:      return -1;    }  // main parameters  argc -= optind;  if(argc < 2 || argc > 5)  {    cerr << argv[0] << ": bad parameters\n";    return -1;  }  fileName = argv[optind++];  if(argc == 2 || argc == 4)  {    if(parseHistSpec(history, divisions, argv[optind++]))    {      cerr << argv[0] << ": bad hist-spec\n";      return -1;    }  }  else  {    history = strtoul(argv[optind++], NULL, 0);    divisions = strtoul(argv[optind++], NULL, 0);  }  // parameters may still be buggy  if(!history || !divisions)  {    cerr << argv[0] << ": hist-sz or x-div can't be zero\n";    return -1;  }  offset = divisions - (history % divisions) + 1;  // optional limiting factors  if(argc == 4 || argc == 5)  {    loLimit = strtod(argv[optind++], NULL);    hiLimit = strtod(argv[optind++], NULL);    autoLimit = false;  }  else    autoLimit = true;  return 0;}void deleteFifo(){  if (unlink(fileName)) {    cerr << "Error deleting fifo: " << strerror(errno) << "\n";  }}intcreateFifo(){  umask(0000);  int res = mkfifo(fileName, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP 		   | S_IROTH | S_IWOTH);  if (res) {    cerr << "Error creating fifo: " << strerror(errno) << "\n";    return -1;  }  if (atexit(deleteFifo))     cerr << "Could not register atexit function. Proceeding anyway\n";  return 0;}intmain(int argc, char* argv[]) try{  // parameters  glutInit(&argc, argv);  if(parseOptions(argc, argv))    return Trend::args;  // initialize rr buffers  rrData = new rr<Value>(history);  rrBuf = new Value[history];  rrEnd = rrBuf + history;  fillRr(NAN);  if (fifo) {    if (createFifo())      return Trend::fifo_error;  }  // start the producer thread  pthread_t thrd;  pthread_mutex_init(&mutex, NULL);  pthread_create(&thrd, NULL, producer, argv[0]);  // display, main mindow and callbacks  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  glutCreateWindow(title? title: argv[0]);  glutReshapeFunc(reshape);  glutDisplayFunc(display);  glutKeyboardFunc(keyboard);  glutMouseFunc(mouse);  glutMotionFunc(motion);  // first redraw  init();  idle(0);  // processing  glutMainLoop();  return Trend::success;}catch(const std::exception& e){  std::cerr << argv[0] << ": " << e.what() << std::endl;  throw;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -