Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickups2/src/network/TrafficControl.cc @ 3015

Last change on this file since 3015 was 2896, checked in by landauf, 16 years ago

Merged gui branch back to trunk.

I did 2 small changes in IngameManager.cc on line 777 and 888 (yes, really), because const_reverse_iterator strangely doesn't work on MinGW.

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