]> git.tdb.fi Git - netvis.git/blob - source/host.cpp
Prevent crashing if the Resolver jams
[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         activity(0),
28         throttle(0)
29 {
30         in_addr ina;
31         ina.s_addr = htonl(addr);
32         name = inet_ntoa(ina);
33         short_name = name;
34 }
35
36 void Host::set_name(const string &n)
37 {
38         name = n;
39
40         if(local)
41         {
42                 unsigned dot = name.find('.');
43                 short_name = name.substr(0, dot);
44         }
45         else
46         {
47                 unsigned dot = name.size();
48                 for(unsigned i=0; (dot>0 && dot!=string::npos); ++i)
49                 {
50                         unsigned prev = name.rfind('.', dot-1);
51                         if(prev+15<name.size() && i>1)
52                                 break;
53                         dot = prev;
54                 }
55
56                 if(dot==string::npos)
57                         short_name = name;
58                 else
59                         short_name = "..."+name.substr(dot+1);
60         }
61 }
62
63 void Host::set_local(bool l)
64 {
65         local = l;
66 }
67
68 void Host::set_position(const Vector2 &p)
69 {
70         pos = p;
71 }
72
73 void Host::set_active(bool a)
74 {
75         active = a;
76 }
77
78 void Host::add_activity(unsigned bytes)
79 {
80         activity += bytes*0.06935;
81 }
82
83 float Host::send_packet()
84 {
85         float ret = throttle;
86         if(throttle<1)
87                 throttle += 0.025;
88         return ret;
89 }
90
91 void Host::tick(const Msp::Time::TimeDelta &td)
92 {
93         float dt = td/Msp::Time::sec;
94
95         activity *= pow(0.933f, dt);
96         throttle -= dt;
97         if(throttle<0)
98                 throttle = 0;
99
100         if(!active)
101                 return;
102
103         const map<unsigned, Host *> &hosts = netvis.get_hosts();
104         float fx = -pos.x*0.1;
105         float fy = -pos.y*0.1;
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/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 }