Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/libraries/network/Connection.cc @ 7788

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

merged network5 into presentation2 branch (untested)

  • Property svn:eol-style set to native
File size: 6.7 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    assert(peer);
85    outgoingEvent outEvent = { peer, outgoingEventType::disconnectPeer, (ENetPacket*)10, 15 };
86   
87    this->outgoingEventsMutex_->lock();
88    this->outgoingEvents_.push_back(outEvent);
89    this->outgoingEventsMutex_->unlock();
90  }
91
92  void Connection::addPacket(ENetPacket *packet, ENetPeer *peer, uint8_t channelID)
93  {
94    assert(peer);
95    outgoingEvent outEvent = { peer, outgoingEventType::sendPacket, packet, channelID };
96   
97    this->outgoingEventsMutex_->lock();
98    this->outgoingEvents_.push_back(outEvent);
99    this->outgoingEventsMutex_->unlock();
100  }
101 
102  void Connection::broadcastPacket(ENetPacket* packet, uint8_t channelID)
103  {
104    outgoingEvent outEvent = { (ENetPeer*)15, outgoingEventType::broadcastPacket, packet, channelID };
105   
106    this->outgoingEventsMutex_->lock();
107    this->outgoingEvents_.push_back(outEvent);
108    this->outgoingEventsMutex_->unlock();
109  }
110
111 
112  void Connection::communicationThread()
113  {
114    COUT(0) << "starting communication thread" << endl;
115    ENetEvent event;
116   
117    while( bCommunicationThreadRunning_ )
118    {
119      // Receive all pending incoming Events (such as packets, connects and disconnects)
120      while( enet_host_check_events( this->host_, &event ) > 0 )
121      {
122//         COUT(0) << "incoming event" << endl;
123        // received an event
124        this->incomingEventsMutex_->lock();
125        this->incomingEvents_.push_back(event);
126        this->incomingEventsMutex_->unlock();
127      }
128     
129      // Send all waiting outgoing packets
130      this->outgoingEventsMutex_->lock();
131      uint32_t outgoingEventsCount = this->outgoingEvents_.size();
132      this->outgoingEventsMutex_->unlock();
133      while( outgoingEventsCount > 0 )
134      {
135//         COUT(0) << "outgoing event" << endl;
136        this->outgoingEventsMutex_->lock();
137        outgoingEvent outEvent = this->outgoingEvents_.front();
138        this->outgoingEvents_.pop_front();
139        this->outgoingEventsMutex_->unlock();
140       
141        switch( outEvent.type )
142        {
143          case outgoingEventType::sendPacket:
144            enet_peer_send( outEvent.peer, outEvent.channelID, outEvent.packet );
145            break;
146          case outgoingEventType::disconnectPeer:
147            enet_peer_disconnect(outEvent.peer, 0);
148            break;
149          case outgoingEventType::broadcastPacket:
150            enet_host_broadcast( this->host_, outEvent.channelID, outEvent.packet );
151            break;
152          default:
153            assert(0);
154        }
155        this->outgoingEventsMutex_->lock();
156        outgoingEventsCount = this->outgoingEvents_.size();
157        this->outgoingEventsMutex_->unlock();
158      }
159     
160      // Wait for incoming events (at most NETWORK_WAIT_TIMEOUT ms)
161      if( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
162      {
163//         COUT(0) << "incoming event after wait" << endl;
164        //received an event
165        this->incomingEventsMutex_->lock();
166        this->incomingEvents_.push_back(event);
167        this->incomingEventsMutex_->unlock();
168      }
169    }
170  }
171
172  void Connection::processQueue()
173  {
174    ENetEvent event;
175
176    this->incomingEventsMutex_->lock();
177    uint32_t incomingEventsCount = this->incomingEvents_.size();
178    this->incomingEventsMutex_->unlock();
179    while( incomingEventsCount > 0 )
180    {
181      packet::Packet* p;
182      this->incomingEventsMutex_->lock();
183      event = this->incomingEvents_.front();
184      this->incomingEvents_.pop_front();
185      this->incomingEventsMutex_->unlock();
186     
187      switch(event.type)
188      {
189        // log handling ================
190        case ENET_EVENT_TYPE_CONNECT:
191          addPeer( &event );
192          break;
193        case ENET_EVENT_TYPE_DISCONNECT:
194          removePeer( &event );
195          break;
196        case ENET_EVENT_TYPE_RECEIVE:
197//           COUT(0) << "ENET_EVENT_TYPE_RECEIVE" << endl;
198          p = createPacket( &event );
199          processPacket(p);
200          break;
201        case ENET_EVENT_TYPE_NONE:
202          break;
203      }
204     
205      this->incomingEventsMutex_->lock();
206      incomingEventsCount = this->incomingEvents_.size();
207      this->incomingEventsMutex_->unlock();
208    }
209  }
210
211  packet::Packet* Connection::createPacket(ENetEvent* event)
212  {
213    packet::Packet *p = packet::Packet::createPacket(event->packet, event->peer);
214    return p;
215//     return p->process();
216  }
217 
218  void Connection::enableCompression()
219  {
220    enet_host_compress_with_range_coder( this->host_ );
221  }
222
223
224}
Note: See TracBrowser for help on using the repository browser.