]> git.tdb.fi Git - netvis.git/blob - source/port.cpp
a96e151fcd63c9d82f933d91bfc9b879d469c96e
[netvis.git] / source / port.cpp
1 /* $Id$
2
3 This file is part of NetVis
4 Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
5 Distributed unter the GPL
6 */
7
8 #include <cstdlib>
9 #include <netinet/in.h>
10 #include <netdb.h>
11 #include <msp/gl/immediate.h>
12 #include <msp/gl/matrix.h>
13 #include <msp/gl/meshbuilder.h>
14 #include <msp/gl/texture.h>
15 #include <msp/strings/lexicalcast.h>
16 #include "port.h"
17 #include "netvis.h"
18
19 using namespace std;
20 using namespace Msp;
21
22 Port::Port(NetVis &v, unsigned n):
23         netvis(v),
24         number(n),
25         registered(false),
26         mesh((GL::COLOR4_UBYTE, GL::VERTEX2))
27 {
28         char buf[128];
29         sockaddr_in addr;
30         addr.sin_family = AF_INET;
31         addr.sin_port = ntohs(number);
32         addr.sin_addr.s_addr = 0;
33         int err = getnameinfo(reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_in), 0, 0, buf, sizeof(buf), 0);
34         if(err==0)
35         {
36                 name = buf;
37                 registered = !isdigit(name[0]);
38         }
39         else
40                 name = Msp::lexical_cast<string>(number);
41
42         const map<unsigned, Port *> &ports = netvis.get_ports();
43         unsigned tries = 100;
44         if(ports.size()>100 && !registered)
45                 tries = 10000/ports.size()+1;
46         float best_score = 0;
47         for(unsigned i=0; (i<tries && best_score<1); ++i)
48         {
49                 GL::Color c;
50                 c.r = rand()*1.0/RAND_MAX;
51                 c.g = rand()*1.0/RAND_MAX;
52                 c.b = rand()*1.0/RAND_MAX;
53                 float high = max(max(c.r, c.g), c.b);
54                 c = c*(1.0/high);
55                 if(registered)
56                 {
57                         float low = min(min(c.r, c.g), c.b);
58                         c = (c+-low)*(1/(1-low));
59                 }
60                 else
61                         c = c*0.6+0.4;
62
63                 float score = 2;
64                 for(map<unsigned, Port *>::const_iterator j=ports.begin(); j!=ports.end(); ++j)
65                 {
66                         if(registered && !j->second->is_registered())
67                                 break;
68                         const GL::Color &other = j->second->get_color();
69                         float dr = c.r-other.r;
70                         float dg = c.g-other.g;
71                         float db = c.b-other.b;
72                         score = min(score, dr*dr+dg*dg+db*db);
73                 }
74                 if(score>best_score)
75                 {
76                         best_score = score;
77                         color = c;
78                 }
79         }
80         color.a = 0.4f;
81
82         GL::MeshBuilder bld(mesh);
83         bld.begin(GL::QUADS);
84         bld.color(color.r, color.g, color.b, color.a);
85         for(unsigned x=0; x<=4; x+=2)
86         {
87                 bld.vertex(x+0, 0);
88                 bld.vertex(x+10, 0);
89                 bld.vertex(x+10, 10);
90                 bld.vertex(x+0, 10);
91         }
92         bld.end();
93 }
94
95 void Port::add_activity(unsigned bytes)
96 {
97         activity.add_bytes(bytes);
98 }
99
100 void Port::tick(const Time::TimeDelta &dt)
101 {
102         activity.tick(dt);
103 }
104
105 void Port::render() const
106 {
107         GL::MatrixStack::Push push_(GL::MatrixStack::modelview());
108         mesh.draw();
109         {
110                 GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2));
111                 imm.begin(GL::QUADS);
112                 imm.color(color.r, color.g, color.b, color.a);
113                 unsigned x = static_cast<unsigned>(activity.get_average()/4096);
114                 imm.vertex(14, 0);
115                 imm.vertex(14+x, 0);
116                 imm.vertex(14+x, 10);
117                 imm.vertex(14, 10);
118                 imm.end();
119         }
120         GL::MatrixStack::modelview() *= GL::Matrix::translation(16, 1, 0);
121         GL::MatrixStack::modelview() *= GL::Matrix::scaling(10);
122         netvis.get_font().draw_string(name);
123         GL::Texture::unbind();
124 }