]> git.tdb.fi Git - netvis.git/blob - source/host.cpp
Move activity tracking to a separate class
[netvis.git] / source / host.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 <cmath>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11 #include <msp/gl/immediate.h>
12 #include <msp/gl/matrix.h>
13 #include <msp/gl/texture.h>
14 #include <msp/gl/transform.h>
15 #include <msp/time/units.h>
16 #include "host.h"
17 #include "netvis.h"
18
19 using namespace std;
20 using namespace Msp;
21
22 Host::Host(NetVis &nv, unsigned a):
23         netvis(nv),
24         addr(a),
25         local(false),
26         active(true),
27         throttle(0)
28 {
29         in_addr ina;
30         ina.s_addr = htonl(addr);
31         name = inet_ntoa(ina);
32         short_name = name;
33 }
34
35 void Host::set_name(const string &n)
36 {
37         name = n;
38
39         if(local)
40         {
41                 unsigned dot = name.find('.');
42                 short_name = name.substr(0, dot);
43         }
44         else
45         {
46                 unsigned dot = name.size();
47                 for(unsigned i=0; (dot>0 && dot!=string::npos); ++i)
48                 {
49                         unsigned prev = name.rfind('.', dot-1);
50                         if(prev+15<name.size() && i>1)
51                                 break;
52                         dot = prev;
53                 }
54
55                 if(dot==string::npos)
56                         short_name = name;
57                 else
58                         short_name = "..."+name.substr(dot+1);
59         }
60 }
61
62 void Host::set_local(bool l)
63 {
64         local = l;
65 }
66
67 void Host::set_position(const Vector2 &p)
68 {
69         pos = p;
70 }
71
72 void Host::set_active(bool a)
73 {
74         active = a;
75 }
76
77 void Host::add_activity(unsigned bytes)
78 {
79         activity.add_bytes(bytes);
80 }
81
82 float Host::send_packet()
83 {
84         float ret = throttle;
85         if(throttle<1)
86                 throttle += 0.025;
87         return ret;
88 }
89
90 void Host::tick(const Msp::Time::TimeDelta &td)
91 {
92         float dt = td/Msp::Time::sec;
93
94         activity.tick(td);
95         throttle -= dt;
96         if(throttle<0)
97                 throttle = 0;
98
99         if(!active)
100                 return;
101
102         const map<unsigned, Host *> &hosts = netvis.get_hosts();
103         float fx = -pos.x*0.1;
104         float fy = -pos.y*0.1;
105         for(map<unsigned, Host *>::const_iterator i=hosts.begin(); i!=hosts.end(); ++i)
106         {
107                 if(i->second!=this)
108                 {
109                         const Vector2 &other_pos = i->second->get_position();
110                         float dx = other_pos.x-pos.x;
111                         float dy = other_pos.y-pos.y;
112                         float d2 = dx*dx+dy*dy;
113                         float d = sqrt(d2);
114
115                         unsigned other_addr = i->second->get_address();
116                         unsigned matching_bits = 0;
117                         for(unsigned j=32; (j-- && !((addr^other_addr)>>j));)
118                                 ++matching_bits;
119
120                         float optimal_dist = 100+(24-min(matching_bits, 24U))*12;
121                         float f = 5000.0*(1.0/optimal_dist-1.0/d);
122
123                         fx += dx/d*f;
124                         fy += dy/d*f;
125                 }
126         }
127
128         if(fx<-4 || fx>4)
129                 pos.x += fx*dt;
130         if(fy<-4 || fy>4)
131                 pos.y += fy*dt;
132 }
133
134 void Host::render() const
135 {
136         if(!active)
137                 return;
138
139         GL::PushMatrix push_;
140         GL::translate(static_cast<int>(pos.x), static_cast<int>(pos.y), 0);
141
142         GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2));
143         imm.begin(GL::QUADS);
144         imm.color(1.0f, 1.0f, 1.0f, max(min(static_cast<float>(activity.get_average()/10000), 1.0f), 0.2f));
145         imm.vertex(-5, -5);
146         imm.vertex(5, -5);
147         imm.vertex(5, 5);
148         imm.vertex(-5, 5);
149         imm.end();
150
151         const GL::Font &font = netvis.get_font();
152         GL::translate(-static_cast<int>(font.get_string_width(short_name)*5), 6, 0);
153         GL::scale_uniform(10);
154
155         imm.color(1.0f, 1.0f, 1.0f);
156         font.draw_string(short_name, imm);
157         GL::Texture::unbind();
158 }