Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/network/TrafficControl.cc @ 2833

Last change on this file since 2833 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

  • Property svn:eol-style set to native
File size: 10.7 KB
RevLine 
[2355]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 <scheusso [at] ee.ethz.ch>, (C) 2008
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TrafficControl.h"
30
31#include "synchronisable/Synchronisable.h"
[2382]32#include "core/ConfigValueIncludes.h"
[2355]33
34#include <cassert>
35#include <boost/bind.hpp>
36
37namespace orxonox {
38
[2485]39  static const unsigned int SCHED_PRIORITY_OFFSET = (unsigned int)-1;
40
[2355]41  objInfo::objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched)
[2485]42  {
43    objID = ID; objCreatorID = creatorID; objCurGS = curGsID; objDiffGS = diffGsID; objSize = size; objValuePerm = prioperm; objValueSched = priosched;
[2355]44  }
[2485]45
[2355]46  objInfo::objInfo()
[2485]47  {
48    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objCurGS = GAMESTATEID_INITIAL; objDiffGS = objCurGS; objSize = 0; objValuePerm = 0; objValueSched = 0;
[2355]49  }
[2485]50
51
52
[2355]53  obj::obj()
[2485]54  {
55    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objSize = 0; objDataOffset = 0;
[2355]56  }
57  obj::obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset )
58  {
59    objID = ID; objCreatorID = creatorID; objSize = size; objDataOffset = offset;
60  }
[2485]61
[2355]62/**
63*Initializing protected members
64*/
65        TrafficControl *TrafficControl::instance_=0;
[2485]66
[2355]67        /**
68        * @brief Constructor: assures that only one reference will be created and sets the pointer
69        */
70        TrafficControl::TrafficControl()
71        {
[2413]72    RegisterObject(TrafficControl);
[2355]73          assert(instance_==0);
74          instance_=this;
[2413]75    this->setConfigValues();
[2355]76        }
[2485]77
[2355]78        /**
79        * @brief Destructor: resets the instance pointer to 0
80        */
81        TrafficControl::~TrafficControl()
[2416]82        {
[2355]83          instance_=0;
84        }
85
86/**
87*Definition of public members
88*/
89
[2413]90  void TrafficControl::setConfigValues()
91  {
[2416]92    SetConfigValue ( bActive_, true );
[2413]93    SetConfigValue ( targetSize, 5000 );
94  }
[2485]95
[2355]96  /**
[2416]97  * sort-algorithm for sorting the objectlist after priorities
[2355]98  */
[2416]99  bool TrafficControl::prioritySort(uint32_t clientID, obj i, obj j)
[2355]100  {
101    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
102    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
103    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
[2485]104
[2355]105    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
106    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
107    return prio1 < prio2;
108  }
109
[2416]110  /**
111  * sort-algorithm for sorting the objectList after position in original data stream
112  */
113  bool TrafficControl::dataSort(obj i, obj j)
114  {
115    int pos1 = i.objDataOffset;
116    int pos2 = j.objDataOffset;
117    return pos1 < pos2;
118  }
[2355]119
[2416]120
[2485]121
[2355]122        void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj> *list)
123        {
124//        copiedVector = *list;
125          currentClientID=clientID;
126          currentGamestateID=gamestateID;
127          evaluateList(clientID, list);
128          return;
129        }
[2485]130
[2382]131  TrafficControl *TrafficControl::getInstance()
132  {
133    assert(instance_);
134    return instance_;
135  }
[2485]136
[2381]137        void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
[2355]138        {
139          std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
[2485]140
[2355]141    //assertions to make sure the maps already exist
142    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
143    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
144          assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
[2485]145
[2355]146    for(itvec = clientListTemp_[clientID][gamestateID].begin(); itvec != clientListTemp_[clientID][gamestateID].end(); itvec++)
147          {
148      if(clientListPerm_[clientID].find((*itvec).objID) != clientListPerm_[clientID].end()) // check whether the obj already exists in our lists
149      {
[2378]150        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
151        clientListPerm_[clientID][(*itvec).objID].objValueSched = 0; //set scheduling value back
[2355]152      }
153      else
154      {
[2381]155        assert(0);
[2355]156        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
157        clientListPerm_[clientID][(*itvec).objID].objID = (*itvec).objID;
158        clientListPerm_[clientID][(*itvec).objID].objCreatorID = (*itvec).objCreatorID;
159        clientListPerm_[clientID][(*itvec).objID].objSize = (*itvec).objSize;
160      }
161          }
162           // remove temporary list (with acked objects) from the map
163    clientListTemp_[clientID].erase( clientListTemp_[clientID].find(gamestateID) );
164        }
165
166/**
167*Definition of private members
168*/
[2418]169
[2355]170        /**
171        *updateClientListPerm
172        *returns void
173        */
174        void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
[2485]175        {
[2355]176          std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
177//        itperm = (clientListPerm_).find(clientID);
178//        assert(itperm != clientListPerm_.end() );
179    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
180    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
181//        itperm->second.insert(std::pair<unsigned int, objInfo>(objid,objinf));
182//     permObjPrio_.insert(objid, objinf.objValuePerm);
183        }
[2485]184
[2355]185  /**
186  * updateClientListTemp
187  * takes the shortened list which will be sent to the gsmanager and puts the *info into clientListTemp
[2485]188  */
[2355]189  void TrafficControl::updateClientListTemp(std::list<obj> *list)
190  {
191    clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(*list);
192  }
193
194  /**
195  *cut
196  *takes the current list that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
197  */
198  void TrafficControl::cut(std::list<obj> *list, unsigned int targetsize)
199  {
200    unsigned int size=0;
[2381]201    std::list<obj>::iterator itvec, ittemp;
[2355]202    assert(!list->empty());
[2381]203    for(itvec = list->begin(); itvec != list->end();)
[2355]204    {
205      assert( (*itvec).objSize < 1000);
[2378]206      if ( ( size + (*itvec).objSize ) < targetsize )
[2355]207      {
208        size += (*itvec).objSize;//objSize is given in bytes
[2381]209        ++itvec;
[2355]210      }
211      else
212      {
[2381]213        clientListPerm_[currentClientID][(*itvec).objID].objValueSched += SCHED_PRIORITY_OFFSET; // NOTE: SCHED_PRIORITY_OFFSET is negative
[2355]214        list->erase(itvec++);
215      }
[2381]216//       printList(list, currentClientID);
[2355]217    }
218    assert(!list->empty());
219  }
220
221
222        /**
223        *evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
224        */
225        void TrafficControl::evaluateList(unsigned int clientID, std::list<obj> *list)
226        {
[2485]227
[2355]228          //now the sorting
[2485]229
[2355]230          //compare listToProcess vs clientListPerm
231    //if listToProcess contains new Objects, add them to clientListPerm
232    std::list<obj>::iterator itvec;
233          for( itvec=list->begin(); itvec != list->end(); itvec++)
234          {
235            if ( clientListPerm_[clientID].find( (*itvec).objID) != clientListPerm_[clientID].end() )
236      {
237        // we already have the object in our map
238        //obj bleibt in liste und permanente prio wird berechnet
239        clientListPerm_[clientID][(*itvec).objID].objDiffGS = currentGamestateID - clientListPerm_[clientID][(*itvec).objID].objCurGS;
240        continue;//check next objId
241      }
242      else
243      {
244        // insert the object into clientListPerm
245        insertinClientListPerm(clientID,*itvec);
246        continue;//check next objId
247      }
248    }
249          //end compare listToProcess vs clientListPerm
[2485]250
[2418]251    if( bActive_ )
[2355]252    {
[2418]253      //sort copied list according to priorities
254      // use boost bind here because we need to pass a memberfunction to stl sort
255      list->sort(boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
[2485]256
[2418]257      //now we check, that the creator of an object always exists on a client
258      std::list<obj>::iterator itcreator;
259      for(itvec = list->begin(); itvec != list->end(); itvec++)
[2485]260      {
[2418]261        fixCreatorDependencies(itvec, list, clientID);
[2355]262      }
[2418]263      //end of sorting
[2485]264      //now the cutting, work the same obj out in processobjectlist and copiedlist, compression rate muss noch festgelegt werden.
[2419]265//       printList(list, clientID);
[2418]266      cut(list, targetSize);
[2485]267
[2418]268      //now sort again after objDataOffset
269      list->sort(boost::bind(&TrafficControl::dataSort, this, _1, _2) );
[2355]270    }
271    //diese Funktion updateClientList muss noch gemacht werden
272    updateClientListTemp(list);
273    //end of sorting
274  }
275
276  void TrafficControl::printList(std::list<obj> *list, unsigned int clientID)
277  {
278    std::list<obj>::iterator it;
279    COUT(0) << "=========== Objectlist ===========" << endl;
280    for( it=list->begin(); it!=list->end(); it++)
[2381]281      COUT(0) << "ObjectID: " << (*it).objID << " creatorID: " << (*it).objCreatorID << " Priority: " << clientListPerm_[clientID][(*it).objID].objValuePerm + clientListPerm_[clientID][(*it).objID].objValueSched << " size: " << (*it).objSize << endl;
[2355]282  }
[2485]283
[2355]284  void TrafficControl::fixCreatorDependencies(std::list<obj>::iterator it1, std::list<obj> *list, unsigned int clientID)
285  {
286    if ( (*it1).objCreatorID == OBJECTID_UNKNOWN )
287      return;
288    if( clientListPerm_[clientID][(*it1).objCreatorID].objCurGS != GAMESTATEID_INITIAL )
289      return;
290    std::list<obj>::iterator it2, it3=it1;
291    for( it2 = ++it3; it2 != list->end(); it2++ )
292    {
293      if( (*it2).objID == (*it1).objCreatorID )
294      {
295        it3 = list->insert(it1, *it2); //insert creator before it1
296        list->erase(it2);
297//         printList(list, clientID);
298        fixCreatorDependencies( it3, list, clientID );
299        break;
300      }
301    }
302  }
[2485]303
[2413]304  void TrafficControl::clientDisconnected(unsigned int clientID)
[2387]305  {
306    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
307    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
308    clientListTemp_.erase(clientListTemp_.find(clientID));
309    clientListPerm_.erase(clientListPerm_.find(clientID));
310  }
[2355]311
312
313}//namespace network
Note: See TracBrowser for help on using the repository browser.