gridkeeper.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * An optimizer for some wireless simulations
  3.  *
  4.  * Helps most when some nodes are mostly stationary.
  5.  * We hope you can share your experience with the gridkeeper with us.
  6.  *
  7.  * Ported from Sun's mobility code
  8.  */
  9. #include "gridkeeper.h"
  10. #include <sys/param.h> /* For MIN/MAX */
  11. static double d2(double x1, double x2, double y1, double y2)
  12. {
  13.   return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
  14. }
  15. GridHandler::GridHandler()
  16. {
  17. }
  18. void GridHandler::handle(Event *e)
  19. {
  20.   MoveEvent *me = (MoveEvent *)e;
  21.   MobileNode **pptr;
  22.   MobileNode * token_ = me->token_;
  23.   if ((pptr = me->leave_)) {
  24.     while (*pptr) {
  25.       if ((*pptr)->address() == token_->address()) break;
  26.       pptr = &((*pptr)->next());
  27.     }
  28.     if (!(*pptr)) abort();
  29.     else {
  30.       *pptr = token_->next();
  31.       token_->next() = 0;
  32.     }
  33.     
  34.   }
  35.   if ((pptr = me->enter_)) {
  36.     if (token_->next()) abort();  // can't be in more than one grid
  37.     token_->next() = *pptr;
  38.     *pptr = token_;
  39.   }
  40.   delete me;
  41.   // dump info in the gridkeeper for debug only
  42.   // dump();
  43. }
  44. GridKeeper* GridKeeper::instance_; 
  45. static class GridKeeperClass : public TclClass {
  46. public:
  47.   GridKeeperClass() : TclClass("GridKeeper") {}
  48.   TclObject* create(int, const char*const*) {
  49.       return (new GridKeeper);
  50.   }
  51. } class_grid_keeper;
  52. GridKeeper::GridKeeper() : size_(0),grid_(NULL), dim_x_(0), dim_y_(0)
  53. {
  54.   gh_ = new GridHandler();
  55. }
  56. GridKeeper::~GridKeeper()
  57. {
  58.   int i;
  59.   for (i = 0; i <= dim_x_; i++) {
  60.     delete [] grid_[i];
  61.   }
  62.   delete [] grid_;
  63. }
  64. int GridKeeper::command(int argc, const char*const* argv)
  65. {
  66.   int i, grid_x, grid_y;
  67.   Tcl& tcl = Tcl::instance();
  68.   MobileNode *mn;
  69.   if (argc == 2) {
  70.     if (strcmp(argv[1], "dump") == 0) {
  71.       dump();
  72.       return (TCL_OK);
  73.     }
  74.   }
  75.   if (argc == 3) {
  76.     if (strcmp(argv[1], "addnode") == 0) {
  77. mn = (MobileNode *)TclObject::lookup(argv[2]);
  78. grid_x = aligngrid((int)mn->X(), dim_x_);
  79.         grid_y = aligngrid((int)mn->Y(), dim_y_);
  80. mn->next() = grid_[grid_x][grid_y];
  81. grid_[grid_x][grid_y] = mn;
  82. size_++;
  83.         return (TCL_OK);
  84.     }
  85.   }
  86.   if (argc == 4 && strcmp(argv[1], "dimension") == 0) {
  87.     if (instance_ == 0) instance_ = this;
  88.     dim_x_ = strtol(argv[2], (char**)0, 0);
  89.     dim_y_ = strtol(argv[3], (char**)0, 0);
  90.     if (dim_x_ <= 0 || dim_y_ <= 0) {
  91.       tcl.result("illegal grid dimension");
  92.       return (TCL_ERROR);
  93.     }
  94.     grid_ = new MobileNode **[dim_x_];
  95.     for (i = 0; i < dim_x_; i++) {
  96.       grid_[i] = new MobileNode *[dim_y_];
  97.       bzero((void *)grid_[i], sizeof(MobileNode *)*dim_y_);
  98.     }
  99.     return (TCL_OK);
  100.   }
  101.   return (TclObject::command(argc, argv));
  102. }
  103. void GridKeeper::new_moves(MobileNode *mn)
  104. {
  105.   double x = mn->X(), y = mn->Y(); 
  106.   double ss = mn->speed();
  107.   double vx = (mn->dX())*ss, vy = (mn->dY())*ss;
  108.   double endx, endy, pother, tm;
  109.   int i, j, endi, gother, grid_x, grid_y;
  110.   MoveEvent *me;
  111.   Scheduler& s = Scheduler::instance();
  112.   endx = mn->destX();
  113.   endy = mn->destY();
  114.   if (vx > 0) {
  115.     endi = MIN(dim_x_-1, (int)endx);
  116.     for (i = (int)x+1; i <= endi; i++) {
  117.       tm = (i-x)/vx;
  118.       pother = vy*tm + y;
  119.       j = (int)pother;
  120.       me = new MoveEvent;
  121.       if (j == pother && j != 0 && j != dim_y_) {
  122. if (vy > 0) gother = j - 1;
  123. else if (vy < 0) gother = j + 1;
  124. else gother = j;
  125.       }
  126.       else {
  127. gother = j;
  128.       }
  129.       me->leave_ = &(grid_[aligngrid(i-1, dim_x_)][aligngrid(gother, dim_y_)]);
  130.       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
  131.       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
  132.       me->enter_ = &(grid_[grid_x][grid_y]);
  133.       me->token_ = mn;
  134.       s.schedule(gh_, me, tm);
  135.     }
  136.   }
  137.   else if (vx < 0) {
  138.     endi = (int)endx;
  139.     for (i = (int)x; i > endi; i--) {
  140.       if (i == dim_x_) continue;
  141.       tm = (i-x)/vx;
  142.       pother = vy*tm + y;
  143.       j = (int)pother;
  144.       me = new MoveEvent;
  145.       if (j == pother && j != 0 && j != dim_y_) {
  146. if (vy > 0) gother = j - 1;
  147. else if (vy < 0) gother = j + 1;
  148. else gother = j;
  149.       }
  150.       else {
  151. gother = j;
  152.       }
  153.       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(gother, dim_y_)];
  154.       me->grid_x_ = grid_x = aligngrid(i-1, dim_x_);
  155.       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
  156.       me->enter_ = &grid_[grid_x][grid_y];
  157.       me->token_ = mn;
  158.       s.schedule(gh_, me, tm);
  159.     }
  160.   }
  161.   if (vy > 0) {
  162.     endi = MIN(dim_y_-1, (int)endy);
  163.     for (j = (int)y+1; j <= endi; j++) {
  164.       tm = (j-y)/vy;
  165.       pother = vx*tm + x;
  166.       i = (int)pother;
  167.       me = new MoveEvent;
  168.       if (i == pother && i != 0 && i != dim_x_ && vx != 0) continue;
  169.       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(j-1, dim_y_)];
  170.       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
  171.       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
  172.       me->enter_ = &grid_[grid_x][grid_y];
  173.       me->token_ = mn;
  174.       s.schedule(gh_, me, tm);
  175.     }
  176.   }
  177.   else if (vy < 0) {
  178.     endi = (int)endy;
  179.     for (j = (int)y; j > endi; j--) {
  180.       if (j == dim_y_) continue;
  181.       tm = (j-y)/vy;
  182.       pother = vx*tm + x;
  183.       i = (int)pother;
  184.       me = new MoveEvent;
  185.       if (i == pother && i != 0 && i != dim_x_ && vx != 0) continue;
  186.       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(j, dim_y_)];
  187.       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
  188.       me->grid_y_ = grid_y = aligngrid(j-1, dim_y_);
  189.       me->enter_ = &grid_[grid_x][grid_y];
  190.       me->token_ = mn;
  191.       s.schedule(gh_, me, tm);
  192.     }
  193.   }
  194. }
  195. int GridKeeper::get_neighbors(MobileNode* mn, MobileNode **output)
  196. {
  197.   int grid_x, grid_y, index = 0, i, j, ulx, uly, lly, adj;
  198.   MobileNode *pgd;
  199.   double mnx, mny, mnr, sqmnr;
  200.   
  201.   mn->update_position();
  202.   mnx = mn->X();
  203.   mny = mn->Y();
  204.   grid_x = aligngrid((int)mn->X(), dim_x_);
  205.   grid_y = aligngrid((int)mn->Y(), dim_y_);
  206.   mnr = mn->radius();
  207.   sqmnr = mnr * mnr;
  208.   adj = (int)ceil(mnr);
  209.   ulx = MIN(dim_x_-1, grid_x + adj);
  210.   uly = MIN(dim_y_-1, grid_y + adj);
  211.   lly = MAX(0, grid_y - adj);
  212.   for (i = MAX(0, grid_x - adj); i <= ulx; i++) {
  213.     for (j = lly; j <= uly; j++) {
  214.       for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
  215. if (mn->address() == pgd->address()) 
  216. continue;
  217. pgd->update_position();
  218. if (d2(pgd->X(), mnx, pgd->Y(), mny) < sqmnr)
  219.  output[index++] = pgd;
  220.       }
  221.     }
  222.   }
  223.   return index;
  224. }
  225. void GridKeeper::dump()
  226. {
  227.     int i,j;
  228.     MobileNode *pgd;
  229.     for (i = 0; i< dim_x_; i++) {
  230.       for (j = 0; j < dim_y_; j++) {
  231. if (grid_[i][j] == 0) continue;
  232. printf("grid[%d][%d]: ",i,j);
  233. for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
  234.   printf("%d ",pgd->address());
  235. }
  236. printf("n");
  237.       }
  238.     }
  239.     printf("-------------------------------n");
  240. }