Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network5/src/libraries/network/Connection.cc @ 7777

Last change on this file since 7777 was 7777, checked in by scheusso, 13 years ago

some () structural changes
some functional changes (GamestateClient replaced through GamestateManager on client)
reliable packets get buffered until a recent gamestate arrived and got processed

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Oliver Scheuss
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "Connection.h"
30
31#include <cassert>
32#include <deque>
33#define WIN32_LEAN_AND_MEAN
34#include <enet/enet.h>
35#include <boost/thread.hpp>
36#include <boost/thread/mutex.hpp>
37#include <boost/date_time.hpp>
38
39#include "packet/Packet.h"
40
41namespace orxonox
42{
43  const boost::posix_time::millisec NETWORK_COMMUNICATION_THREAD_WAIT_TIME(20);
44
45  Connection::Connection():
46    host_(0), bCommunicationThreadRunning_(false)
47  {
48    enet_initialize();
49    atexit(enet_deinitialize);
50    this->incomingEventsMutex_ = new boost::mutex;
51    this->outgoingEventsMutex_ = new boost::mutex;
52  }
53
54  Connection::~Connection()
55  {
56    delete this->incomingEventsMutex_;
57    delete this->outgoingEventsMutex_;
58  }
59
60  void Connection::startCommunicationThread()
61  {
62    this->bCommunicationThreadRunning_ = true;
63    this->communicationThread_ = new boost::thread(&Connection::communicationThread, this);
64  }
65 
66  void Connection::stopCommunicationThread()
67  {
68    this->bCommunicationThreadRunning_ = false;
69    if( !this->communicationThread_->timed_join(NETWORK_COMMUNICATION_THREAD_WAIT_TIME) )
70    {
71      // force thread to stop
72      this->communicationThread_->interrupt();
73    }
74    delete this->communicationThread_;
75  }
76
77
78//   int Connection::service(ENetEvent* event) {
79//     return enet_host_service( this->host_, event, NETWORK_WAIT_TIMEOUT );
80//   }
81
82  void Connection::disconnectPeer(ENetPeer *peer)
83  {
84    outgoingEvent outEvent = { peer, outgoingEventType::disconnectPeer, (ENetPacket*)10, 15 };
85   
86    this->outgoingEventsMutex_->lock();
87    this->outgoingEvents_.push_back(outEvent);
88    this->outgoingEventsMutex_->unlock();
89  }
90
91  void Connection::addPacket(ENetPacket *packet, ENetPeer *peer, uint8_t channelID)
92  {
93    outgoingEvent outEvent = { peer, outgoingEventType::sendPacket, packet, channelID };
94   
95    this->outgoingEventsMutex_->lock();
96    this->outgoingEvents_.push_back(outEvent);
97    this->outgoingEventsMutex_->unlock();
98  }
99 
100  void Connection::broadcastPacket(ENetPacket* packet, uint8_t channelID)
101  {
102    outgoingEvent outEvent = { 0, outgoingEventType::broadcastPacket, packet, channelID };
103   
104    this->outgoingEventsMutex_->lock();
105    this->outgoingEvents_.push_back(outEvent);
106    this->outgoingEventsMutex_->unlock();
107  }
108
109 
110  void Connection::communicationThread()
111  {
112    COUT(0) << "starting communication thread" << endl;
113    ENetEvent event;
114   
115    while( bCommunicationThreadRunning_ )
116    {
117      // Receive all pending incoming Events (such as packets, connects and disconnects)
118      while( enet_host_check_events( this->host_, &event ) > 0 )
119      {
120//         COUT(0) << "incoming event" << endl;
121        // received an event
122        this->incomingEventsMutex_->lock();
123        this->incomingEvents_.push_back(event);
124        this->incomingEventsMutex_->unlock();
125      }
126     
127      // Send all waiting outgoing packets
128      this->outgoingEventsMutex_->lock();
129      uint32_t outgoingEventsCount = this->outgoingEvents_.size();
130      this->outgoingEventsMutex_->unlock();
131      while( outgoingEventsCount > 0 )
132      {
133//         COUT(0) << "outgoing event" << endl;
134        this->outgoingEventsMutex_->lock();
135        outgoingEvent outEvent = this->outgoingEvents_.front();
136        this->outgoingEvents_.pop_front();
137        this->outgoingEventsMutex_->unlock();
138       
139        switch( outEvent.type )
140        {
141          case outgoingEventType::sendPacket:
142            enet_peer_send( outEvent.peer, outEvent.channelID, outEvent.packet );
143            break;
144          case outgoingEventType::disconnectPeer:
145            enet_peer_disconnect(outEvent.peer, 0);
146            break;
147          case outgoingEventType::broadcastPacket:
148            enet_host_broadcast( this->host_, outEvent.channelID, outEvent.packet );
149            break;
150          default:
151            assert(0);
152        }
153        this->outgoingEventsMutex_->lock();
154        outgoingEventsCount = this->outgoingEvents_.size();
155        this->outgoingEventsMutex_->unlock();
156      }
157     
158      // Wait for incoming events (at most NETWORK_WAIT_TIMEOUT ms)
159      if( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
160      {
161//         COUT(0) << "incoming event after wait" << endl;
162        //received an event
163        this->incomingEventsMutex_->lock();
164        this->incomingEvents_.push_back(event);
165        this->incomingEventsMutex_->unlock();
166      }
167    }
168  }
169
170  void Connection::processQueue()
171  {
172    ENetEvent event;
173
174    this->incomingEventsMutex_->lock();
175    uint32_t incomingEventsCount = this->incomingEvents_.size();
176    this->incomingEventsMutex_->unlock();
177    while( incomingEventsCount > 0 )
178    {
179      packet::Packet* p;
180      this->incomingEventsMutex_->lock();
181      event = this->incomingEvents_.front();
182      this->incomingEvents_.pop_front();
183      this->incomingEventsMutex_->unlock();
184     
185      switch(event.type)
186      {
187        // log handling ================
188        case ENET_EVENT_TYPE_CONNECT:
189          addPeer( &event );
190          break;
191        case ENET_EVENT_TYPE_DISCONNECT:
192          removePeer( &event );
193          break;
194        case ENET_EVENT_TYPE_RECEIVE:
195//           COUT(0) << "ENET_EVENT_TYPE_RECEIVE" << endl;
196          p = createPacket( &event );
197          processPacket(p);
198          break;
199        case ENET_EVENT_TYPE_NONE:
200          break;
201      }
202     
203      this->incomingEventsMutex_->lock();
204      incomingEventsCount = this->incomingEvents_.size();
205      this->incomingEventsMutex_->unlock();
206    }
207  }
208
209  packet::Packet* Connection::createPacket(ENetEvent* event)
210  {
211    packet::Packet *p = packet::Packet::createPacket(event->packet, event->peer);
212    return p;
213//     return p->process();
214  }
215 
216  void Connection::enableCompression()
217  {
218    enet_host_compress_with_range_coder( this->host_ );
219  }
220
221
222}
Note: See TracBrowser for help on using the repository browser.