]> git.tdb.fi Git - netvis.git/blob - source/host.cpp
fca3a304e545d29eefafd8201958020c92b6470e
[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 center_force = (local ? 0.5 : 0.1);
104         float fx = -pos.x*center_force;
105         float fy = -pos.y*center_force;
106         for(map<unsigned, Host *>::const_iterator i=hosts.begin(); i!=hosts.end(); ++i)
107         {
108                 if(i->second!=this)
109                 {
110                         const Vector2 &other_pos = i->second->get_position();
111                         float dx = other_pos.x-pos.x;
112                         float dy = other_pos.y-pos.y;
113                         float d2 = dx*dx+dy*dy;
114                         float d = sqrt(d2);
115
116                         unsigned other_addr = i->second->get_address();
117                         unsigned matching_bits = 0;
118                         for(unsigned j=32; (j-- && !((addr^other_addr)>>j));)
119                                 ++matching_bits;
120
121                         float optimal_dist = 100+(24-min(matching_bits, 24U))*12;
122                         float f = 5000.0*(1.0/optimal_dist-1.0/d);
123
124                         fx += dx/d*f;
125                         fy += dy/d*f;
126                 }
127         }
128
129         if(fx<-4 || fx>4)
130                 pos.x += fx*dt;
131         if(fy<-4 || fy>4)
132                 pos.y += fy*dt;
133 }
134
135 void Host::render() const
136 {
137         if(!active)
138                 return;
139
140         GL::PushMatrix push_;
141         GL::translate(static_cast<int>(pos.x), static_cast<int>(pos.y), 0);
142
143         GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2));
144         imm.begin(GL::QUADS);
145         imm.color(1.0f, 1.0f, 1.0f, max(min(static_cast<float>(activity.get_average()/10000), 1.0f), 0.2f));
146         imm.vertex(-5, -5);
147         imm.vertex(5, -5);
148         imm.vertex(5, 5);
149         imm.vertex(-5, 5);
150         imm.end();
151
152         const GL::Font &font = netvis.get_font();
153         GL::translate(-static_cast<int>(font.get_string_width(short_name)*5), 6, 0);
154         GL::scale_uniform(10);
155
156         imm.color(1.0f, 1.0f, 1.0f);
157         font.draw_string(short_name, imm);
158         GL::Texture::unbind();
159 }