📄 netmodel.cc
字号:
else bot = nymin_ - (nymax_ - nymin_); NamDrop *d = new NamDrop(x, y, bot, ehn->edge->PacketHeight(), e.time, e.offset, e.pe.pkt); d->paint(pno); d->insert(&animations_); break; }}void NetModel::addView(NetView* p){ p->next_ = views_; views_ = p;}NamNode *NetModel::lookupNode(int nn) const{ for (NamNode* n = nodes_; n != 0; n = n->next_) if (n->num() == nn) return (n); /* XXX */ fprintf(stderr, "nam: no such node %d\n", nn); exit(1);}int NetModel::command(int argc, const char *const *argv){ Tcl& tcl = Tcl::instance(); if (argc == 2) { if (strcmp(argv[1], "layout") == 0) { /* * <net> layout * Compute reasonable defaults for missing node or edge * sizes based on the maximum link delay. Lay out the * nodes and edges as specified in the layout file. */ scale_estimate(); layout(); return (TCL_OK); } } else if (argc == 3) { if (strcmp(argv[1], "view") == 0) { /* * <net> view <viewName> * Create the window for the network layout/topology. */ NetView *v = new NetView(argv[2], this); v->next_ = views_; views_ = v; return (TCL_OK); } } else if (argc >= 4 && strcmp(argv[1], "node") == 0) { /* * <net> node <name> <shape> [<size>] * Create a node using the specified name * and the default size and insert it into this * NetModel's list of drawables. */ double size = defsize; if (argc > 4) size = atof(argv[4]); NamNode *n; if (!strcmp(argv[3], "circle")) n = new CircleNode(argv[2], size); else if (!strcmp(argv[3], "box")) n = new BoxNode(argv[2], size); else n = new HexagonNode(argv[2], size); n->next_ = nodes_; nodes_ = n; n->insert(&drawables_); return (TCL_OK); } else if (argc == 4) { if (strcmp(argv[1], "color") == 0) { /* * <net> color <packetClass> <colorName> * Display packets of the specified class using * the specified color. */ int c = atoi(argv[2]); if ((u_int)c > 1024) { tcl.resultf("%s color: class %d out of range", argv[0], c); return (TCL_ERROR); } Paint *paint = Paint::instance(); if (c > nclass_) { int n, i; for (n = nclass_; n < c; n <<= 1); int *p = new int[n]; for (i = 0; i < nclass_; ++i) p[i] = paint_[i]; delete paint_; paint_ = p; nclass_ = n; int pno = paint->thin(); for (; i < n; ++i) paint_[i] = pno; } int pno = paint->lookup(Tk_GetUid((char *)argv[3]), 1); if (pno < 0) { tcl.resultf("%s color: no such color: %s", argv[0], argv[3]); return (TCL_ERROR); } paint_[c] = pno; return (TCL_OK); } if (strcmp(argv[1], "ncolor") == 0) { /* * <net> ncolor <node> <colorName> * set color of node to the specified color. */ Paint *paint = Paint::instance(); NamNode *n = lookupNode(atoi(argv[2])); int pno = paint->lookup(Tk_GetUid((char *)argv[3]), 3); if (pno < 0) { tcl.resultf("%s ncolor: no such color: %s", argv[0], argv[3]); return (TCL_ERROR); } n->paint(pno); return (TCL_OK); } } else if (argc == 5) { if (strcmp(argv[1], "queue") == 0) { /* * <net> queue <src> <dst> <angle> * Create a queue for the edge from 'src' to 'dst'. * Add it to this NetModel's queue list. * Display the queue at the specified angle from * the edge to which it belongs. */ int src = atoi(argv[2]); int dst = atoi(argv[3]); EdgeHashNode *h = lookupEdge(src, dst); if (h == 0) { tcl.resultf("%s queue: no such edge (%d,%d)", argv[0], src, dst); return (TCL_ERROR); } /* XXX can we assume no duplicate queues? */ double angle = atof(argv[4]); NamEdge *e = h->edge; angle += e->angle(); NamQueue *q = new NamQueue(angle); h->queue = q; q->next_ = queues_; queues_ = q; return (TCL_OK); } if (strcmp(argv[1], "ecolor") == 0) { /* * <net> ecolor <src> <dst> <colorName> * set color of edge to the specified color. */ Paint *paint = Paint::instance(); EdgeHashNode* h = lookupEdge(atoi(argv[2]), atoi(argv[3])); if (h == 0) { tcl.resultf("%s ecolor: no such edge (%s,%s)", argv[0], argv[2], argv[3]); return (TCL_ERROR); } int pno = paint->lookup(Tk_GetUid((char *)argv[4]), 3); if (pno < 0) { tcl.resultf("%s ncolor: no such color: %s", argv[0], argv[3]); return (TCL_ERROR); } h->edge->paint(pno); return (TCL_OK); } } else if (argc == 7) { if (strcmp(argv[1], "link") == 0) { /* * <net> link <src> <dst> <bandwidth> <delay> <angle> * Create a link/edge between the specified source * and destination. Add it to this NetModel's list * of drawables and to the source's list of links. */ NamNode *src = lookupNode(atoi(argv[2])); NamNode *dst = lookupNode(atoi(argv[3])); double bw = atof(argv[4]); double delay = atof(argv[5]); double angle = atof(argv[6]); NamEdge *e = new NamEdge(src, dst, defsize, bw, delay, angle); enterEdge(e); e->insert(&drawables_); src->add_link(e); tcl.resultf("%g", delay); return (TCL_OK); } } /* If no NetModel commands matched, try the Object commands. */ return (TclObject::command(argc, argv));}void NetModel::placeEdge(NamEdge* e, NamNode* src) const{ if (e->marked() == 0) { NamNode *dst = e->neighbor(); double nsin = sin(M_PI * e->angle()); double ncos = cos(M_PI * e->angle()); double x0 = src->x() + src->size() * ncos * .75; double y0 = src->y() + src->size() * nsin * .75; double x1 = dst->x() - dst->size() * ncos * .75; double y1 = dst->y() - dst->size() * nsin * .75; e->place(x0, y0, x1, y1); /* Place the queue here too. */ EdgeHashNode *h = lookupEdge(e->src(), e->dst()); if (h->queue != 0) h->queue->place(e->size(), e->x0(), e->y0()); e->mark(); }}void NetModel::layout(){ /* If there is no fixed node, anchor the first one entered at (0,0). */ NamNode *n; for (n = nodes_; n != 0; n = n->next_) n->mark(0); if (nodes_) nodes_->place(0., 0.); int did_something; do { did_something = 0; for (n = nodes_; n != 0; n = n->next_) did_something |= traverse(n); } while (did_something); for (n = nodes_; n != 0; n = n->next_) for (NamEdge* e = n->links(); e != 0; e = e->next_) placeEdge(e, n);}void NetModel::move(double& x, double& y, double angle, double d) const{ x += d * cos(M_PI * angle); y += d * sin(M_PI * angle);}/* * Traverse node n's neighbors and place them based on the * delay of their links to n. The two branches of the if..else * are to handle unidirectional links -- we place ourselves if * we haven't been placed & our downstream neighbor has. */int NetModel::traverse(NamNode* n){ int did_something = 0; for (NamEdge* e = n->links(); e != 0; e = e->next_) { NamNode *neighbor = e->neighbor(); double d = e->delay() + (n->size() + neighbor->size()) * 0.75; if (n->marked() && !neighbor->marked()) { double x = n->x(); double y = n->y(); move(x, y, e->angle(), d); neighbor->place(x, y); did_something |= traverse(neighbor); if (nymax_ < y) nymax_ = y; if (nymin_ > y) nymin_ = y; } else if (!n->marked() && neighbor->marked()) { double x = neighbor->x(); double y = neighbor->y(); move(x, y, e->angle(), -d); n->place(x, y); did_something = 1; } } return (did_something);}/* * Compute reasonable defaults for missing node or edge sizes * based on the maximum link delay. */void NetModel::scale_estimate(){ /* Determine the maximum link delay. */ double emax = 0.; NamNode *n; for (n = nodes_; n != 0; n = n->next_) { for (NamEdge* e = n->links(); e != 0; e = e->next_) if (e->delay() > emax) emax = e->delay(); } /* * Check for missing node or edge sizes. If any are found, * compute a reasonable default based on the maximum edge * dimension. */ for (n = nodes_; n != 0; n = n->next_) { if (n->size() <= 0.) n->size(.1 * emax); for (NamEdge* e = n->links(); e != 0; e = e->next_) if (e->size() <= 0.) e->size(.03 * emax); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -